Trader_Interfaces.cpp

Go to the documentation of this file.
00001 // Trader_Interfaces.cpp,v 1.72 2006/04/25 11:35:29 jwillemsen Exp
00002 
00003 #ifndef TAO_TRADER_INTERFACES_CPP
00004 #define TAO_TRADER_INTERFACES_CPP
00005 
00006 #include "orbsvcs/Trader/Trader_Interfaces.h"
00007 #include "orbsvcs/Trader/Trader_T.h"
00008 #include "ace/INET_Addr.h"
00009 #include "orbsvcs/Trader/Trader_Constraint_Visitors.h"
00010 #include "ace/OS_NS_time.h"
00011 #include "ace/OS_NS_unistd.h"
00012 
00013 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00014 
00015 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
00016 TAO_Lookup<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
00017 TAO_Lookup (TAO_Trader<TRADER_LOCK_TYPE,MAP_LOCK_TYPE> &trader)
00018   : TAO_Trader_Components<POA_CosTrading::Lookup> (trader.trading_components ()),
00019     TAO_Support_Attributes<POA_CosTrading::Lookup> (trader.support_attributes ()),
00020     TAO_Import_Attributes<POA_CosTrading::Lookup> (trader.import_attributes ()),
00021     IDS_SAVED (100),
00022     trader_ (trader)
00023 {
00024 }
00025 
00026 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
00027 TAO_Lookup<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::~TAO_Lookup (void)
00028 {
00029   ACE_GUARD (TRADER_LOCK_TYPE, trader_mon, this->lock_);
00030   for (Request_Ids::ITERATOR riter (this->request_ids_);
00031        ! riter.done ();
00032        riter.advance ())
00033     {
00034       CosTrading::Admin::OctetSeq** old_seq = 0;
00035       riter.next (old_seq);
00036       delete *old_seq;
00037     }
00038 }
00039 
00040 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE> void
00041 TAO_Lookup<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
00042 query (const char *type,
00043        const char *constraint,
00044        const char *preferences,
00045        const CosTrading::PolicySeq &in_policies,
00046        const CosTrading::Lookup::SpecifiedProps &desired_props,
00047        CORBA::ULong how_many,
00048        CosTrading::OfferSeq_out returned_offers,
00049        CosTrading::OfferIterator_out returned_offer_iterator,
00050        CosTrading::PolicyNameSeq_out returned_limits_applied
00051        ACE_ENV_ARG_DECL)
00052   ACE_THROW_SPEC ((CORBA::SystemException,
00053                    CosTrading::IllegalServiceType,
00054                    CosTrading::UnknownServiceType,
00055                    CosTrading::IllegalConstraint,
00056                    CosTrading::Lookup::IllegalPreference,
00057                    CosTrading::Lookup::IllegalPolicyName,
00058                    CosTrading::Lookup::PolicyTypeMismatch,
00059                    CosTrading::Lookup::InvalidPolicyValue,
00060                    CosTrading::IllegalPropertyName,
00061                    CosTrading::DuplicatePropertyName,
00062                    CosTrading::DuplicatePolicyName))
00063 {
00064   // Instantiate a class to help interpret query policies.
00065   TAO_Policies policies (this->trader_, in_policies ACE_ENV_ARG_PARAMETER);
00066   ACE_CHECK;
00067 
00068   // If a federated query returns to us, ignore it to prevent
00069   // redundant results and infinite loops.
00070   CosTrading::Admin::OctetSeq* request_id = 0;
00071   int check = this->seen_request_id (policies, request_id ACE_ENV_ARG_PARAMETER);
00072   ACE_CHECK;
00073 
00074   if (check)
00075     {
00076       returned_offers = new CosTrading::OfferSeq;
00077       returned_limits_applied = new CosTrading::PolicyNameSeq;
00078       return;
00079     }
00080 
00081   // The presence of a link interface determines whether we should
00082   // attempt to forward or propagate queries.
00083   CosTrading::Link_ptr link_if =
00084     this->trader_.trading_components ().link_if ();
00085 
00086   // If the importer has specified a starting trader, foward the
00087   // query.
00088   CosTrading::TraderName* trader_name =
00089     policies.starting_trader (ACE_ENV_SINGLE_ARG_PARAMETER);
00090   ACE_CHECK;
00091 
00092   if (! CORBA::is_nil (link_if) && trader_name != 0)
00093     {
00094       CosTrading::PolicySeq policies_to_forward;
00095       policies.copy_to_forward (policies_to_forward, *trader_name);
00096       const char* next_hop = (*trader_name)[0];
00097       this->forward_query (next_hop,
00098                            type,
00099                            constraint,
00100                            preferences,
00101                            policies_to_forward,
00102                            desired_props,
00103                            how_many,
00104                            returned_offers,
00105                            returned_offer_iterator,
00106                            returned_limits_applied
00107                            ACE_ENV_ARG_PARAMETER);
00108       ACE_CHECK;
00109       return;
00110     }
00111 
00112   // Retrieve the type description struct from the Service Type Repos.
00113   const TAO_Support_Attributes_i& support_attrs =
00114     this->trader_.support_attributes ();
00115   CosTradingRepos::ServiceTypeRepository_ptr rep =
00116     support_attrs.service_type_repos ();
00117   CosTradingRepos::ServiceTypeRepository::TypeStruct_var type_struct =
00118     rep->fully_describe_type (type ACE_ENV_ARG_PARAMETER);
00119   ACE_CHECK;
00120 
00121   // @@ Should throw a NO_MEMORY exception here...
00122   ACE_NEW (returned_offers,
00123            CosTrading::OfferSeq);
00124 
00125   // Obtain a reference to the offer database.
00126   TAO_Offer_Database<MAP_LOCK_TYPE>& offer_database =
00127     this->trader_.offer_database ();
00128 
00129   // TAO_Offer_Filter -- ensures that we don't consider offers with
00130   // modifiable or dynamic properties if the Trader doesn't support
00131   // them, or the importer has turned them off using policies.
00132   // TAO_Constraint_Validator -- validates the constraint with the
00133   // property types in the supplied type.  TAO_Constraint_Interpreter
00134   // -- parses the constraint string, and determines whether an offer
00135   // meets those constraints.  TAO_Preference_Interpreter -- parses
00136   // the preference string and orders offers according to those
00137   // constraints.
00138   TAO_Offer_Filter offer_filter (policies
00139                                  ACE_ENV_ARG_PARAMETER);
00140   ACE_CHECK;
00141   TAO_Trader_Constraint_Validator validator (type_struct.in ());
00142   TAO_Constraint_Interpreter constr_inter (validator,
00143                                            constraint
00144                                            ACE_ENV_ARG_PARAMETER);
00145   ACE_CHECK;
00146   TAO_Preference_Interpreter pref_inter (validator,
00147                                          preferences
00148                                          ACE_ENV_ARG_PARAMETER);
00149   ACE_CHECK;
00150 
00151   // Try to find the map of offers of desired service type.
00152   offer_filter.configure_type (type_struct.ptr ());
00153   this->lookup_one_type (type,
00154                          offer_database,
00155                          constr_inter,
00156                          pref_inter,
00157                          offer_filter);
00158 
00159   CORBA::Boolean result = policies.exact_type_match (ACE_ENV_SINGLE_ARG_PARAMETER);
00160   ACE_CHECK;
00161 
00162   if (!result)
00163     {
00164       // If the importer hasn't demanded an exact match search, we
00165       // search all the subtypes of the supplied type. NOTE: Only the
00166       // properties belonging to the provided type are considered on
00167       // subtypes. Additional properties on the subtype are generally
00168       // ignored. This is as it should be, consistent with the notions
00169       // of type inheritence.
00170       this->lookup_all_subtypes (type,
00171                                  type_struct->incarnation,
00172                                  offer_database,
00173                                  rep,
00174                                  constr_inter,
00175                                  pref_inter,
00176                                  offer_filter
00177                                  ACE_ENV_ARG_PARAMETER);
00178       ACE_CHECK;
00179     }
00180 
00181   // Take note of the limits applied in this query.
00182   returned_limits_applied = offer_filter.limits_applied ();
00183 
00184   // Fill the return sequence and iterator with the bountiful results.
00185   CORBA::ULong offers_returned =
00186     this->fill_receptacles (type,
00187                             how_many,
00188                             desired_props,
00189                             policies,
00190                             pref_inter,
00191                             *returned_offers.ptr (),
00192                             returned_offer_iterator
00193                             ACE_ENV_ARG_PARAMETER);
00194   ACE_CHECK;
00195 
00196   // The following steps are only appropriate for a linked trader.
00197   if (! CORBA::is_nil (link_if))
00198     {
00199       // Determine if we should perform a federated query, and if so
00200       // construct a sequence of links to follow.
00201       CosTrading::LinkNameSeq_var links;
00202       CORBA::Boolean should_follow =
00203         this->retrieve_links (policies,
00204                               offers_returned,
00205                               CosTrading::LinkNameSeq_out (links.out ())
00206                               ACE_ENV_ARG_PARAMETER);
00207       ACE_CHECK;
00208 
00209       if (should_follow && links->length () != 0)
00210         {
00211           // Query those links we've accumulated!
00212           this->federated_query (links.in (),
00213                                  policies,
00214                                  *request_id,
00215                                  pref_inter,
00216                                  type,
00217                                  constraint,
00218                                  preferences,
00219                                  desired_props,
00220                                  how_many,
00221                                  *returned_offers.ptr (),
00222                                  returned_offer_iterator.ptr (),
00223                                  *returned_limits_applied.ptr ()
00224                                  ACE_ENV_ARG_PARAMETER);
00225           ACE_CHECK;
00226         }
00227     }
00228 }
00229 
00230 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
00231 void
00232 TAO_Lookup<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
00233 lookup_one_type (const char* type,
00234                  TAO_Offer_Database<MAP_LOCK_TYPE>& offer_database,
00235                  TAO_Constraint_Interpreter& constr_inter,
00236                  TAO_Preference_Interpreter& pref_inter,
00237                  TAO_Offer_Filter& offer_filter)
00238 {
00239   // Retrieve an iterator over the offers for a given type.
00240   // @@ Would have used Offer_Database::offer_iterator for less
00241   // coupling between TAO_Lookup and Offer_Database, but g++ barfs on
00242   // that.
00243 #if defined(_MSC_VER)
00244   TAO_Offer_Database<MAP_LOCK_TYPE>::offer_iterator
00245     offer_iter (type, offer_database);
00246 #else
00247   // MSVC won't grok this for some reason, but it's necessary for the
00248   // HP compiler, which seriously requires the typename keyword
00249   // here. I apologize if this ifdef offends some ACE users'
00250   // sensibilities --- it certainly offends mine.
00251   ACE_TYPENAME TAO_Offer_Database<MAP_LOCK_TYPE>::offer_iterator
00252     offer_iter (type, offer_database);
00253 #endif
00254 
00255   while (offer_filter.ok_to_consider_more () &&
00256          offer_iter.has_more_offers ())
00257     {
00258       // For each offer in the iterator, attempt to match it with
00259       // the constraints passed to the Query method. If it matches
00260       // the constraint, use the TAO_Preference_Interpreter to
00261       // order the matched offers with respect to the preference
00262       // string passed to the method. All the while the offer
00263       // filter ensures we don't exceed the match cardinality
00264       // constraints.
00265       CosTrading::Offer* offer = offer_iter.get_offer ();
00266 
00267       TAO_Trader_Constraint_Evaluator evaluator (offer);
00268       if (offer_filter.ok_to_consider (offer) &&
00269           constr_inter.evaluate (evaluator))
00270         {
00271           // Shove the offer and its id into the preference
00272           // ordering object, pref_inter.
00273           CosTrading::OfferId offer_id = offer_iter.get_id ();
00274           pref_inter.order_offer (evaluator, offer, offer_id);
00275           offer_filter.matched_offer ();
00276         }
00277 
00278       offer_iter.next_offer ();
00279     }
00280 }
00281 
00282 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
00283 void
00284 TAO_Lookup<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
00285 lookup_all_subtypes (const char* type,
00286                      CosTradingRepos::ServiceTypeRepository::IncarnationNumber& inc_num,
00287                      TAO_Offer_Database<MAP_LOCK_TYPE>& offer_database,
00288                      CosTradingRepos::ServiceTypeRepository_ptr rep,
00289                      TAO_Constraint_Interpreter& constr_inter,
00290                      TAO_Preference_Interpreter& pref_inter,
00291                      TAO_Offer_Filter& offer_filter
00292                      ACE_ENV_ARG_DECL)
00293 {
00294   // BEGIN SPEC
00295   // The trader may return a service offer of a subtype of the "type"
00296   // requested. Sub-typing of service types is discussed in "Service
00297   // Types" on page 16-4. A service subtype can be described by the
00298   // properties of its supertypes. This ensures that a well-formed query
00299   // for the "type" is also a well-formed query with respect to any
00300   // subtypes. However, if the importer specifies the policy of
00301   // exact_type_match = TRUE, then only offers with the exact (no
00302   // subtype) service type requested are returned.
00303   // END SPEC
00304 
00305   CosTradingRepos::ServiceTypeRepository::SpecifiedServiceTypes sst;
00306   CosTradingRepos::ServiceTypeRepository::ServiceTypeNameSeq_var all_types;
00307 
00308   // Optimization: Since a subtype can't have a higher incarnation
00309   // number than a supertype, we don't need to consider those
00310   // types with lower incarnation numbers.
00311   sst.incarnation (inc_num);
00312 
00313   all_types = rep->list_types (sst ACE_ENV_ARG_PARAMETER);
00314   ACE_CHECK;
00315 
00316   // Scan all types inserted after the super types. If the transitive
00317   // closure of a type's super type relation includes the super type
00318   // being considered, then perform a search on that type.
00319   CORBA::ULong num_types = all_types->length ();
00320   CosTradingRepos::ServiceTypeRepository::TypeStruct_var type_struct;
00321   for (CORBA::ULong i = 0;
00322        i < num_types && offer_filter.ok_to_consider_more ();
00323        i++)
00324     {
00325       // Obtain a description of the prospective type.
00326       type_struct = rep->fully_describe_type (all_types[i]
00327                                               ACE_ENV_ARG_PARAMETER);
00328       ACE_CHECK;
00329 
00330       CosTradingRepos::ServiceTypeRepository::ServiceTypeNameSeq&
00331         super_types = type_struct->super_types;
00332       CORBA::ULong num_super_types = super_types.length ();
00333 
00334       for (CORBA::ULong j = 0; j < num_super_types; j++)
00335         {
00336           if (ACE_OS::strcmp (type_struct->super_types[j], type) == 0)
00337             {
00338               // Egads, a subtype! This type has the type passed
00339               // to query in its list of super_types.
00340               offer_filter.configure_type (type_struct.ptr ());
00341               this->lookup_one_type (all_types[i],
00342                                      offer_database,
00343                                      constr_inter,
00344                                      pref_inter,
00345                                      offer_filter);
00346               break;
00347             }
00348         }
00349     }
00350 }
00351 
00352 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
00353 int
00354 TAO_Lookup<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
00355 fill_receptacles (const char* /* type */,
00356                   CORBA::ULong how_many,
00357                   const CosTrading::Lookup::SpecifiedProps& desired_props,
00358                   TAO_Policies& policies,
00359                   TAO_Preference_Interpreter& pref_inter,
00360                   CosTrading::OfferSeq& offers,
00361                   CosTrading::OfferIterator_ptr& offer_itr
00362                   ACE_ENV_ARG_DECL)
00363   ACE_THROW_SPEC ((CosTrading::IllegalPropertyName,
00364                   CosTrading::DuplicatePropertyName))
00365 {
00366   // BEGIN SPEC
00367   // The returned offers are passed back in one of two ways (or a
00368   // combination of both). ?The "offers" return result conveys a list
00369   // of offers and the "offer_itr" is a reference to an interface at
00370   // which offers can be obtained. ?The "how_many" parameter states
00371   // how many offers are to be returned via the "offers" result, any
00372   // remaining offers are available via the iterator interface. If the
00373   // "how_many" exceeds the number of offers to be returned, then the
00374   // "offer_itr" will be nil.
00375   // END SPEC
00376 
00377   TAO_Property_Filter prop_filter (desired_props ACE_ENV_ARG_PARAMETER);
00378   ACE_CHECK_RETURN (0);
00379 
00380   // RETURNING: Calculate how many offers go into the sequence
00381   //  Calculate how many go into the iterator
00382 
00383   CORBA::ULong return_card = policies.return_card (ACE_ENV_SINGLE_ARG_PARAMETER);
00384   ACE_CHECK_RETURN (0);
00385 
00386   CORBA::ULong i = 0;
00387   CORBA::ULong size = static_cast<CORBA::ULong> (pref_inter.num_offers ());
00388   CORBA::ULong offers_in_sequence = (how_many < size) ? how_many : size;
00389   CORBA::ULong offers_in_iterator = size - offers_in_sequence;
00390 
00391   // Ensure the total number of offers returned doesn't exceed return_card.
00392   offers_in_sequence = offers_in_sequence > return_card
00393     ? return_card
00394     : offers_in_sequence;
00395 
00396   return_card -= offers_in_sequence;
00397 
00398   offers_in_iterator = offers_in_iterator > return_card
00399     ? return_card
00400     : offers_in_iterator;
00401 
00402   CORBA::ULong total_offers = offers_in_sequence + offers_in_iterator;
00403   offers.length (offers_in_sequence);
00404 
00405   // Add to the sequence, filtering out the undesired properties.
00406   for (i = 0; i < offers_in_sequence; i++)
00407     {
00408       CosTrading::Offer* offer = 0;
00409       CosTrading::OfferId offer_id = 0;
00410 
00411       // Pull the next ordered offer out of the preference
00412       // interpreter.
00413       pref_inter.remove_offer (offer, offer_id);
00414 
00415       // Filter out the undesired properties.
00416       prop_filter.filter_offer (offer, offers[i]);
00417       CORBA::string_free (offer_id);
00418     }
00419 
00420   // Any remaining offers under the return_card go into iterator
00421   if (offers_in_iterator > 0)
00422     {
00423       // Create an iterator implementation
00424       TAO_Offer_Iterator *oi =
00425         this->create_offer_iterator (prop_filter);
00426 
00427       // Register it with the POA.
00428       offer_itr = oi->_this (ACE_ENV_SINGLE_ARG_PARAMETER);
00429       ACE_CHECK_RETURN (total_offers - offers_in_iterator);
00430 
00431       oi->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
00432       ACE_CHECK_RETURN (total_offers - offers_in_iterator);
00433 
00434       // Add to the iterator
00435       for (i = 0; i < offers_in_iterator; i++)
00436         {
00437           CosTrading::Offer* offer = 0;
00438           CosTrading::OfferId offer_id = 0;
00439 
00440           // Pull the next ordered offer out of the preference
00441           // intrerpreter and add it to the offer iterator.
00442           pref_inter.remove_offer (offer, offer_id);
00443           oi->add_offer (offer_id, offer);
00444         }
00445     }
00446 
00447   // Clear the preference intrerpreter of superfluous items.
00448   size_t num_offers = pref_inter.num_offers ();
00449   for (size_t j = 0; j < num_offers; j++)
00450     {
00451       CosTrading::Offer* offer = 0;
00452       CosTrading::OfferId offer_id = 0;
00453 
00454       pref_inter.remove_offer (offer, offer_id);
00455       CORBA::string_free (offer_id);
00456     }
00457 
00458   return total_offers;
00459 }
00460 
00461 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
00462 TAO_Offer_Iterator *
00463 TAO_Lookup<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
00464 create_offer_iterator (const TAO_Property_Filter& pfilter)
00465 {
00466   // This is the factory method that creates the appropriate type of
00467   // offer iterator. If there's no Register interface, then we can
00468   // just stick the offers directly into an iterator, since these
00469   // offers will never be removed from the Trader. If there's a
00470   // Register interface, then there's a chance that by the time the
00471   // importer calls the next_n method on the iterator that the offer
00472   // will have been withdrawn. So the Register_Offer_Iterator retains only
00473   // the offer ids, and will recognize when an offer id no longer
00474   // identifies an offer in the trader.
00475 
00476   // We pass the property filter to the iterators, so when the iterators
00477   // return the offers, they can remove the undesirable properties
00478   // from those offers.
00479   TAO_Offer_Iterator* iterator = 0;
00480 
00481   if (CORBA::is_nil (this->trader_.trading_components ().register_if ()))
00482     ACE_NEW_RETURN (iterator,
00483                     TAO_Query_Only_Offer_Iterator (pfilter),
00484                     0);
00485   else
00486     ACE_NEW_RETURN (iterator,
00487                     TAO_Register_Offer_Iterator<MAP_LOCK_TYPE> (this->trader_.offer_database (),
00488                                                                 pfilter),
00489                     0);
00490   return iterator;
00491 }
00492 
00493 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
00494 CORBA::Boolean
00495 TAO_Lookup<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
00496 retrieve_links (TAO_Policies& policies,
00497                 CORBA::ULong offers_returned,
00498                 CosTrading::LinkNameSeq_out links
00499                 ACE_ENV_ARG_DECL)
00500   ACE_THROW_SPEC ((CORBA::SystemException,
00501                    CosTrading::Lookup::PolicyTypeMismatch))
00502 {
00503   CORBA::Boolean should_follow = 0;
00504   CosTrading::FollowOption follow_rule = policies.link_follow_rule (ACE_ENV_SINGLE_ARG_PARAMETER);
00505   ACE_CHECK_RETURN (should_follow);
00506 
00507   // Determine whether or not a federated query is warranted. A query
00508   // is waranted if the follow_rule governing this query is 'always'
00509   // or if_no_local and the local query returned nothing.
00510   if ((follow_rule == CosTrading::always ||
00511        (follow_rule == CosTrading::if_no_local && offers_returned == 0)))
00512     {
00513       CORBA::ULong hc = policies.hop_count (ACE_ENV_SINGLE_ARG_PARAMETER);
00514       ACE_CHECK_RETURN (0);
00515 
00516       if (hc > 0)
00517         should_follow = 1;
00518     }
00519 
00520   if (should_follow)
00521     {
00522       // Grab the names of all the links in the trader, and push
00523       // the suitable ones onto <valid_links>.
00524       CosTrading::Link_ptr link_if =
00525         this->trader_.trading_components ().link_if ();
00526 
00527       links = link_if->list_links (ACE_ENV_SINGLE_ARG_PARAMETER);
00528       ACE_CHECK_RETURN (0);
00529 
00530       // Determine which of the links registered with the Link
00531       // interface are suitable to follow.
00532       CORBA::ULong i = 0, j = 0,
00533         length = links->length ();
00534 
00535       for (i = 0; i < length; i++)
00536         {
00537           // Grab the link information.
00538           CosTrading::Link::LinkInfo_var
00539             link_info (link_if->describe_link (links[i] ACE_ENV_ARG_PARAMETER));
00540           ACE_CHECK_RETURN (should_follow);
00541 
00542           // Compute the link follow rule.
00543           CosTrading::FollowOption link_rule =
00544             policies.link_follow_rule (link_info.in () ACE_ENV_ARG_PARAMETER);
00545           ACE_CHECK_RETURN (should_follow);
00546 
00547           // Determine if the link follow rule applies.
00548           if (link_rule == CosTrading::always
00549               || (link_rule == CosTrading::if_no_local
00550                   && offers_returned == 0))
00551             {
00552               // Add the link to the list of links to follow.
00553               if (i > j)
00554                 links[j] = links[i];
00555 
00556               j++;
00557             }
00558         }
00559 
00560       links->length (j);
00561     }
00562 
00563   return should_follow;
00564 }
00565 
00566 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
00567 void
00568 TAO_Lookup<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
00569 federated_query (const CosTrading::LinkNameSeq& links,
00570                  const TAO_Policies& policies,
00571                  const CosTrading::Admin::OctetSeq& request_id,
00572                  TAO_Preference_Interpreter& pref_inter,
00573                  const char *type,
00574                  const char *constr,
00575                  const char *pref,
00576                  const CosTrading::Lookup::SpecifiedProps& desired_props,
00577                  CORBA::ULong how_many,
00578                  CosTrading::OfferSeq& offers,
00579                  CosTrading::OfferIterator_ptr& offer_iter,
00580                  CosTrading::PolicyNameSeq& limits
00581                  ACE_ENV_ARG_DECL)
00582   ACE_THROW_SPEC ((CORBA::SystemException,
00583                    CosTrading::IllegalServiceType,
00584                    CosTrading::UnknownServiceType,
00585                    CosTrading::IllegalConstraint,
00586                    CosTrading::Lookup::IllegalPreference,
00587                    CosTrading::Lookup::IllegalPolicyName,
00588                    CosTrading::Lookup::PolicyTypeMismatch,
00589                    CosTrading::Lookup::InvalidPolicyValue,
00590                    CosTrading::IllegalPropertyName,
00591                    CosTrading::DuplicatePropertyName,
00592                    CosTrading::DuplicatePolicyName))
00593 {
00594   // The general idea here is this: We've assembled a number of links
00595   // to follow, and we'll query each of them in turn. On each query we
00596   // adjust the policies for the new trader by reducing the hop_count,
00597   // changing the link_follow_rule etc..., and merge the results from
00598   // the new query with the results from the previous queries.
00599 
00600   // We'll need the link and admin interfaces for this part of the
00601   // federated query. It's ok to get the admin interface without
00602   // checking if it's nil, becase the conformance criteria dictate
00603   // that a trader can't implement the link interface without the
00604   // admin interface.
00605   CosTrading::Link_ptr link_interface
00606     = this->trader_.trading_components ().link_if ();
00607 
00608   // Begin collecting all the various offer_iterators into a
00609   // collection. The end result is a distributed tree of offer
00610   // iterators, which if traversed in its entirety is probably hugely
00611   // inefficient, but oh well, I can't think of a better solution.
00612   TAO_Offer_Iterator_Collection* offer_iter_collection = 0;
00613   ACE_NEW (offer_iter_collection,
00614            TAO_Offer_Iterator_Collection);
00615   offer_iter_collection->add_offer_iterator (offer_iter);
00616 
00617   CosTrading::PolicySeq policies_to_pass;
00618   policies.copy_to_pass (policies_to_pass, request_id ACE_ENV_ARG_PARAMETER);
00619   ACE_CHECK;
00620 
00621   for (int i = links.length () - 1; i >= 0; i--)
00622     {
00623       CosTrading::OfferSeq *out_offers = 0;
00624       CosTrading::OfferIterator *out_offer_iter = 0;
00625       CosTrading::PolicyNameSeq *out_limits = 0;
00626 
00627       ACE_TRY
00628         {
00629           // Obtain information about the link we're traversing.
00630           CosTrading::Link::LinkInfo_var link_info =
00631             link_interface->describe_link (links[i] ACE_ENV_ARG_PARAMETER);
00632           ACE_TRY_CHECK;
00633 
00634           // Set the link follow policy for the query over the link.
00635           policies.copy_in_follow_option (policies_to_pass,
00636                                           link_info.in ()
00637                                           ACE_ENV_ARG_PARAMETER);
00638           ACE_TRY_CHECK;
00639 
00640           CosTrading::Lookup_var remote_lookup =
00641             CosTrading::Lookup::_duplicate (link_info->target.in ());
00642 
00643           // Perform the federated query.
00644           remote_lookup->query (type,
00645                                 constr,
00646                                 pref,
00647                                 policies_to_pass,
00648                                 desired_props,
00649                                 how_many - offers.length (),
00650                                 CosTrading::OfferSeq_out (out_offers),
00651                                 CosTrading::OfferIterator_out (out_offer_iter),
00652                                 CosTrading::PolicyNameSeq_out (out_limits)
00653                                 ACE_ENV_ARG_PARAMETER);
00654           ACE_TRY_CHECK;
00655 
00656           CORBA::ULong j = 0;
00657           CosTrading::OfferSeq_var out_offers_var (out_offers);
00658           CosTrading::PolicyNameSeq_var out_limits_var (out_limits);
00659 
00660           // Add another iterator to the collection.
00661           if (! CORBA::is_nil (out_offer_iter))
00662             offer_iter_collection->add_offer_iterator (out_offer_iter);
00663 
00664           // Concatenate the limits applied.
00665           CORBA::ULong source_length = out_limits->length (),
00666             target_length = limits.length (),
00667             total_length = source_length + target_length;
00668 
00669           limits.length (total_length);
00670           for (j = 0; j < source_length; j++)
00671             limits[j + target_length] = out_limits_var[j];
00672 
00673           // Concatenate the sequence offers.
00674           source_length = out_offers->length ();
00675           target_length = offers.length ();
00676           total_length = source_length + target_length;
00677 
00678           offers.length (total_length);
00679           for (j = 0; j < source_length; j++)
00680             offers[j + target_length] = out_offers_var[j];
00681         }
00682       ACE_CATCHANY
00683         {
00684           // Ah, well, this query failed, move on to the next one.
00685         }
00686       ACE_ENDTRY;
00687       //      ACE_CHECK;
00688     }
00689 
00690   // Sort the sequence in preference order.
00691   this->order_merged_sequence (pref_inter, offers);
00692 
00693   // Return the collection of offer iterators.
00694   offer_iter = offer_iter_collection->_this (ACE_ENV_SINGLE_ARG_PARAMETER);
00695   ACE_CHECK;
00696 
00697   offer_iter_collection->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
00698   ACE_CHECK;
00699 }
00700 
00701 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
00702 void
00703 TAO_Lookup<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
00704 order_merged_sequence (TAO_Preference_Interpreter& pref_inter,
00705                        CosTrading::OfferSeq& offers)
00706 {
00707   CORBA::ULong j = 0;
00708   CORBA::ULong length = offers.length ();
00709 
00710   // Grab ownership of the offers already in the target sequence.
00711   CosTrading::Offer* target_buf = offers.get_buffer (1);
00712 
00713   // Order the sequence.
00714   for (j = 0; j < length; j++)
00715     pref_inter.order_offer (&target_buf[j]);
00716   //pref_inter.order_offer (&offers[j]);
00717 
00718   // Reallocate the sequence.
00719   offers.length (length);
00720 
00721   //  CosTrading::OfferSeq copy;
00722   //  copy.length (length);
00723 
00724   // Copy in the ordered offers.
00725   for (j = 0; j < length; j++)
00726     {
00727       CosTrading::Offer* offer = 0;
00728       pref_inter.remove_offer (offer);
00729       //copy[j] = *offer;
00730       offers[j] = *offer;
00731     }
00732 
00733   // Release the orphaned memory.
00734   CosTrading::OfferSeq::freebuf (target_buf);
00735   //  offers = copy
00736 }
00737 
00738 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
00739 void
00740 TAO_Lookup<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
00741 forward_query (const char* next_hop,
00742                const char *type,
00743                const char *constr,
00744                const char *pref,
00745                const CosTrading::PolicySeq& policy_seq,
00746                const CosTrading::Lookup::SpecifiedProps& desired_props,
00747                CORBA::ULong how_many,
00748                CosTrading::OfferSeq_out offers,
00749                CosTrading::OfferIterator_out offer_itr,
00750                CosTrading::PolicyNameSeq_out limits_applied
00751                ACE_ENV_ARG_DECL)
00752   ACE_THROW_SPEC ((CORBA::SystemException,
00753                    CosTrading::IllegalServiceType,
00754                    CosTrading::UnknownServiceType,
00755                    CosTrading::IllegalConstraint,
00756                    CosTrading::Lookup::IllegalPreference,
00757                    CosTrading::Lookup::IllegalPolicyName,
00758                    CosTrading::Lookup::PolicyTypeMismatch,
00759                    CosTrading::Lookup::InvalidPolicyValue,
00760                    CosTrading::IllegalPropertyName,
00761                    CosTrading::DuplicatePropertyName,
00762                    CosTrading::DuplicatePolicyName))
00763 {
00764   // Forward this query to the next link in the starting_trader sequence.
00765   CosTrading::Link_ptr link_interface
00766     = this->trader_.trading_components ().link_if ();
00767 
00768   ACE_TRY
00769     {
00770       CosTrading::Link::LinkInfo_var link_info =
00771         link_interface->describe_link (next_hop ACE_ENV_ARG_PARAMETER);
00772       ACE_TRY_CHECK;
00773 
00774       CosTrading::Lookup_var remote_lookup =
00775         CosTrading::Lookup::_duplicate (link_info->target.in ());
00776 
00777       CORBA::Object_var us = this->_this (ACE_ENV_SINGLE_ARG_PARAMETER);
00778       ACE_TRY_CHECK;
00779 
00780       CORBA::Boolean self_loop =
00781         remote_lookup->_is_equivalent (us.in () ACE_ENV_ARG_PARAMETER);
00782       ACE_TRY_CHECK;
00783 
00784       if (! self_loop)
00785         {
00786           // Perform forwarding query.
00787           remote_lookup->query (type,
00788                                 constr,
00789                                 pref,
00790                                 policy_seq,
00791                                 desired_props,
00792                                 how_many,
00793                                 offers,
00794                                 offer_itr,
00795                                 limits_applied
00796                                 ACE_ENV_ARG_PARAMETER);
00797           ACE_TRY_CHECK;
00798         }
00799       else
00800         {
00801           this->query (type,
00802                        constr,
00803                        pref,
00804                        policy_seq,
00805                        desired_props,
00806                        how_many,
00807                        offers,
00808                        offer_itr,
00809                        limits_applied
00810                        ACE_ENV_ARG_PARAMETER);
00811           ACE_TRY_CHECK;
00812         }
00813     }
00814   ACE_CATCHANY
00815     {
00816       CosTrading::Policy policy;
00817       policy.name = TAO_Policies::POLICY_NAMES[TAO_Policies::STARTING_TRADER];
00818       policy.value <<= next_hop;
00819       ACE_TRY_THROW (CosTrading::Lookup::InvalidPolicyValue (policy));
00820     }
00821   ACE_ENDTRY;
00822   //  ACE_CHECK;
00823 }
00824 
00825 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
00826 CORBA::Boolean
00827 TAO_Lookup<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
00828 seen_request_id (TAO_Policies& policies,
00829                  CosTrading::Admin::OctetSeq*& seq
00830                  ACE_ENV_ARG_DECL)
00831   ACE_THROW_SPEC ((CORBA::SystemException,
00832                    CosTrading::Lookup::PolicyTypeMismatch))
00833 {
00834   CORBA::Boolean return_value = 0;
00835 
00836   seq = policies.request_id (ACE_ENV_SINGLE_ARG_PARAMETER);
00837   ACE_CHECK_RETURN (1);
00838 
00839   if (seq == 0)
00840     {
00841       CosTrading::Admin_ptr admin_if =
00842         this->trader_.trading_components ().admin_if ();
00843       seq = admin_if->request_id_stem (ACE_ENV_SINGLE_ARG_PARAMETER);
00844       ACE_CHECK_RETURN (1);
00845     }
00846   else
00847     {
00848       // Allocate memory so memory mangement is the same for both
00849       // cases.
00850       ACE_NEW_THROW_EX (seq,
00851                         CosTrading::Admin::OctetSeq (*seq),
00852                         CORBA::NO_MEMORY ());
00853       ACE_CHECK_RETURN (1);
00854     }
00855 
00856   ACE_GUARD_RETURN (TRADER_LOCK_TYPE, trader_mon, this->lock_, 1);
00857 
00858   for (Request_Ids::ITERATOR riter (this->request_ids_);
00859        ! riter.done ();
00860        riter.advance ())
00861     {
00862       CosTrading::Admin::OctetSeq** old_seq = 0;
00863       riter.next (old_seq);
00864 
00865       if (**old_seq == *seq)
00866         {
00867           return_value = 1;
00868           break;
00869         }
00870     }
00871 
00872   if (return_value == 0)
00873     {
00874       if (this->request_ids_.size () == IDS_SAVED)
00875         {
00876           CosTrading::Admin::OctetSeq* octet_seq = 0;
00877           this->request_ids_.dequeue_head (octet_seq);
00878           delete octet_seq;
00879         }
00880 
00881       this->request_ids_.enqueue_tail (seq);
00882     }
00883 
00884   return return_value;
00885 }
00886 
00887 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
00888 TAO_Register<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::TAO_Register (TAO_Trader<TRADER_LOCK_TYPE,MAP_LOCK_TYPE> &trader)
00889   : TAO_Trader_Components<POA_CosTrading::Register> (trader.trading_components ()),
00890     TAO_Support_Attributes<POA_CosTrading::Register> (trader.support_attributes ()),
00891     trader_ (trader)
00892 {
00893 }
00894 
00895 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
00896 TAO_Register<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::~TAO_Register (void)
00897 {
00898 }
00899 
00900 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
00901 CosTrading::OfferId
00902 TAO_Register<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
00903 _cxx_export (CORBA::Object_ptr reference,
00904              const char *type,
00905              const CosTrading::PropertySeq &properties
00906              ACE_ENV_ARG_DECL)
00907   ACE_THROW_SPEC ((CORBA::SystemException,
00908                   CosTrading::Register::InvalidObjectRef,
00909                   CosTrading::IllegalServiceType,
00910                   CosTrading::UnknownServiceType,
00911                   CosTrading::Register::InterfaceTypeMismatch,
00912                   CosTrading::IllegalPropertyName,
00913                   CosTrading::PropertyTypeMismatch,
00914                   CosTrading::ReadonlyDynamicProperty,
00915                   CosTrading::MissingMandatoryProperty,
00916                   CosTrading::DuplicatePropertyName))
00917 {
00918   // For robustness purposes --
00919   if (CORBA::is_nil (reference))
00920     ACE_THROW_RETURN (CosTrading::Register::InvalidObjectRef (), 0);
00921 
00922   // Get service type map
00923   TAO_Offer_Database<MAP_LOCK_TYPE> &offer_database = this->trader_.offer_database ();
00924 
00925   CosTrading::Offer* offer = 0;
00926   TAO_Support_Attributes_i& support_attrs =
00927     this->trader_.support_attributes ();
00928   CosTradingRepos::ServiceTypeRepository_ptr rep =
00929     support_attrs.service_type_repos ();
00930 
00931   // Yank our friend, the type struct, and confirm that the given
00932   // properties match the type definition.
00933   CosTradingRepos::ServiceTypeRepository::TypeStruct_var type_struct =
00934     rep->fully_describe_type (type ACE_ENV_ARG_PARAMETER);
00935   ACE_CHECK_RETURN (0);
00936 
00937   // Oops the type is masked, we shouldn't let exporters know the type
00938   // exists.
00939   if (type_struct->masked)
00940     ACE_THROW_RETURN (CosTrading::UnknownServiceType (type), 0);
00941 
00942   // TAO-specific way to determine if an object is derived from or is
00943   // an interface type.
00944   int check = (! reference->_is_a (type_struct->if_name ACE_ENV_ARG_PARAMETER));
00945   ACE_CHECK_RETURN (0);
00946   if (check)
00947     ACE_THROW_RETURN (CosTrading::Register::
00948                       InterfaceTypeMismatch (type, reference), 0);
00949 
00950   // Validate that the properties defined for this offer are correct
00951   // to their types and strength.
00952   this->validate_properties (type, type_struct.ptr (), properties ACE_ENV_ARG_PARAMETER);
00953   ACE_CHECK_RETURN (0);
00954 
00955   // CORBA::ULong plength = properties.length ();
00956   ACE_NEW_THROW_EX (offer, CosTrading::Offer, CORBA::NO_MEMORY ());
00957   ACE_CHECK_RETURN (0);
00958 
00959   // No copying, no memory leaks. Violates the "in" parameter semantics
00960   // when this object is colocated with the client, however.
00961   //  CosTrading::PropertySeq* hack_seq =
00962   //    const_cast<CosTrading::PropertySeq*> (&properties);
00963   //  CosTrading::Property* pbuf = hack_seq->get_buffer (1);
00964 
00965   //  CosTrading::PropertySeq* hack_seq =
00966   //    const_cast<CosTrading::PropertySeq*> (&properties);
00967   //  CosTrading::Property* pbuf = hack_seq->get_buffer (0);
00968   //  offer->properties.replace (plength, plength, pbuf, 0);
00969   //  offer->properties._allocate_buffer (plength);
00970   offer->properties = properties;
00971   offer->reference = reference->_duplicate (reference);
00972 
00973   // Insert the offer into the underlying type map.
00974   CosTrading::OfferId id = offer_database.insert_offer (type, offer);
00975 
00976   return id;
00977 }
00978 
00979 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
00980 void
00981 TAO_Register<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
00982 withdraw (const char *id
00983           ACE_ENV_ARG_DECL)
00984   ACE_THROW_SPEC ((CORBA::SystemException,
00985                    CosTrading::IllegalOfferId,
00986                    CosTrading::UnknownOfferId,
00987                    CosTrading::Register::ProxyOfferId))
00988 {
00989   // Get service type map.
00990   TAO_Offer_Database<MAP_LOCK_TYPE> &offer_database = this->trader_.offer_database ();
00991   offer_database.remove_offer ((CosTrading::OfferId) id ACE_ENV_ARG_PARAMETER);
00992 }
00993 
00994 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
00995 CosTrading::Register::OfferInfo *
00996 TAO_Register<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
00997 describe (const char *id
00998           ACE_ENV_ARG_DECL)
00999   ACE_THROW_SPEC ((CORBA::SystemException,
01000                   CosTrading::IllegalOfferId,
01001                   CosTrading::UnknownOfferId,
01002                   CosTrading::Register::ProxyOfferId))
01003 {
01004   // Get service type map.
01005   char* type = 0;
01006   TAO_Offer_Database<MAP_LOCK_TYPE> &offer_database = this->trader_.offer_database ();
01007 
01008   // Perform a lookup to find the offer.
01009   CosTrading::Offer* offer =
01010     offer_database.lookup_offer ((CosTrading::OfferId) id, type ACE_ENV_ARG_PARAMETER);
01011   ACE_CHECK_RETURN (0);
01012 
01013   CosTrading::Register::OfferInfo *offer_info = 0;
01014   ACE_NEW_THROW_EX (offer_info, CosTrading::Register::OfferInfo, CORBA::NO_MEMORY ());
01015   ACE_CHECK_RETURN (0);
01016 
01017   offer_info->reference = CORBA::Object::_duplicate (offer->reference.in ());
01018   offer_info->type = CORBA::string_dup (type);
01019 
01020   // Let the offer_info prop_seq "borrow" the sequence of properties.
01021   //CORBA::ULong length = offer->properties.length ();
01022   //  CosTrading::Property* prop_buf = offer->properties.get_buffer ();
01023   offer_info->properties = offer->properties;
01024 
01025   return offer_info;
01026 }
01027 
01028 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01029 void
01030 TAO_Register<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01031 modify (const char *id,
01032         const CosTrading::PropertyNameSeq& del_list,
01033         const CosTrading::PropertySeq& modify_list
01034         ACE_ENV_ARG_DECL)
01035   ACE_THROW_SPEC ((CORBA::SystemException,
01036                   CosTrading::NotImplemented,
01037                   CosTrading::IllegalOfferId,
01038                   CosTrading::UnknownOfferId,
01039                   CosTrading::Register::ProxyOfferId,
01040                   CosTrading::IllegalPropertyName,
01041                   CosTrading::Register::UnknownPropertyName,
01042                   CosTrading::PropertyTypeMismatch,
01043                   CosTrading::ReadonlyDynamicProperty,
01044                   CosTrading::Register::MandatoryProperty,
01045                   CosTrading::Register::ReadonlyProperty,
01046                   CosTrading::DuplicatePropertyName))
01047 {
01048   // Throw an exception if the trader is not configured
01049   // to support properties modification.
01050   int check =  (! this->supports_modifiable_properties (ACE_ENV_SINGLE_ARG_PARAMETER));
01051   ACE_CHECK;
01052 
01053   if (check)
01054     ACE_THROW (CosTrading::NotImplemented ());
01055 
01056   char* type = 0;
01057   TAO_Support_Attributes_i& support_attrs =
01058     this->trader_.support_attributes ();
01059   CosTradingRepos::ServiceTypeRepository_ptr rep =
01060     support_attrs.service_type_repos ();
01061   TAO_Offer_Database<MAP_LOCK_TYPE> &offer_database = this->trader_.offer_database ();
01062 
01063   CosTrading::Offer* offer = offer_database.
01064     lookup_offer (const_cast<CosTrading::OfferId> (id), type ACE_ENV_ARG_PARAMETER);
01065   ACE_CHECK;
01066 
01067   if (offer != 0)
01068     {
01069       // Yank our friend, the type struct.
01070       CosTradingRepos::ServiceTypeRepository::TypeStruct_var type_struct =
01071         rep->fully_describe_type (type ACE_ENV_ARG_PARAMETER);
01072       ACE_CHECK;
01073       TAO_Offer_Modifier offer_mod (type, type_struct.in (), offer);
01074 
01075       // Delete, add, and change properties of the offer.
01076       offer_mod.delete_properties (del_list ACE_ENV_ARG_PARAMETER);
01077       ACE_CHECK;
01078 
01079       offer_mod.merge_properties (modify_list ACE_ENV_ARG_PARAMETER);
01080       ACE_CHECK;
01081 
01082       // Alter our reference to the offer. We do this last, since the
01083       // spec says: modify either suceeds completely or fails
01084       // completely.
01085       offer_mod.affect_change (modify_list);
01086     }
01087 }
01088 
01089 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01090 void
01091 TAO_Register<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01092 withdraw_using_constraint (const char *type,
01093                            const char *constr
01094                            ACE_ENV_ARG_DECL)
01095   ACE_THROW_SPEC ((CORBA::SystemException,
01096                    CosTrading::IllegalServiceType,
01097                    CosTrading::UnknownServiceType,
01098                    CosTrading::IllegalConstraint,
01099                    CosTrading::Register::NoMatchingOffers))
01100 {
01101   TAO_Support_Attributes_i&
01102     support_attrs = this->trader_.support_attributes ();
01103   CosTradingRepos::ServiceTypeRepository_ptr rep =
01104     support_attrs.service_type_repos ();
01105   TAO_Offer_Database<MAP_LOCK_TYPE> &offer_database =  this->trader_.offer_database ();
01106   CORBA::Boolean dp_support = support_attrs.supports_dynamic_properties ();
01107   TAO_String_Queue ids;
01108 
01109   // Retrieve the type struct
01110   CosTradingRepos::ServiceTypeRepository::TypeStruct_var type_struct =
01111     rep->fully_describe_type (type ACE_ENV_ARG_PARAMETER);
01112   ACE_CHECK;
01113 
01114   // Try to find the map of offers of desired service type.
01115   // @@ Again, should be Offer_Database::offer_iterator
01116   {
01117 #if defined (_MSC_VER)
01118     TAO_Offer_Database<MAP_LOCK_TYPE>::offer_iterator
01119       offer_iter (type, offer_database);
01120 #else
01121     // MSVC won't grok this for some reason, but it's necessary for
01122     // the HP compiler, which seriously requires the typename keyword
01123     // here. I apologize if this ifdef offends some ACE users'
01124     // sensibilities --- it certainly offends mine.
01125     ACE_TYPENAME TAO_Offer_Database<MAP_LOCK_TYPE>::offer_iterator
01126       offer_iter (type, offer_database);
01127 #endif /* _MSC_VER */
01128 
01129     TAO_Trader_Constraint_Validator validator (type_struct.in ());
01130     TAO_Constraint_Interpreter constr_inter (validator, constr ACE_ENV_ARG_PARAMETER);
01131     ACE_CHECK;
01132 
01133     while (offer_iter.has_more_offers ())
01134       {
01135         CosTrading::Offer* offer = offer_iter.get_offer ();
01136         // Add offer if it matches the constraints
01137 
01138         TAO_Trader_Constraint_Evaluator evaluator (offer, dp_support);
01139         if (constr_inter.evaluate (evaluator))
01140           ids.enqueue_tail (offer_iter.get_id ());
01141 
01142         offer_iter.next_offer ();
01143       }
01144   }
01145 
01146   if (ids.size () != 0)
01147     {
01148       while (! ids.is_empty ())
01149         {
01150           char* offer_id = 0;
01151 
01152           ids.dequeue_head (offer_id);
01153           offer_database.remove_offer (offer_id ACE_ENV_ARG_PARAMETER);
01154           ACE_CHECK;
01155           CORBA::string_free (offer_id);
01156         }
01157     }
01158   else
01159     ACE_THROW (CosTrading::Register::NoMatchingOffers (constr));
01160 }
01161 
01162 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01163 CosTrading::Register_ptr
01164 TAO_Register<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01165 resolve (const CosTrading::TraderName &name
01166          ACE_ENV_ARG_DECL)
01167   ACE_THROW_SPEC ((CORBA::SystemException,
01168                   CosTrading::Register::IllegalTraderName,
01169                   CosTrading::Register::UnknownTraderName,
01170                   CosTrading::Register::RegisterNotSupported))
01171 {
01172   // Determine if the first link is a legal link name.
01173   if (! TAO_Trader_Base::is_valid_link_name (name[0]))
01174     ACE_THROW_RETURN (CosTrading::Register::IllegalTraderName (name),
01175                       CosTrading::Register::_nil ());
01176 
01177   // Grab a reference to the link interface, and get a link description.
01178   CosTrading::Link_ptr link_if =
01179     this->trader_.trading_components ().link_if ();
01180 
01181   // Ensure that the link interface is supported.
01182   if (! CORBA::is_nil (link_if))
01183     return CosTrading::Register::_nil ();
01184 
01185   CosTrading::Link::LinkInfo_var link_info;
01186   CosTrading::Register_var remote_reg;
01187 
01188   ACE_TRY
01189     {
01190       // Ensure that the link to the next trader exists.
01191       link_info = link_if->describe_link (name[0] ACE_ENV_ARG_PARAMETER);
01192       ACE_TRY_CHECK;
01193 
01194       remote_reg =
01195         CosTrading::Register::_narrow (link_info->target_reg.in () ACE_ENV_ARG_PARAMETER);
01196       ACE_TRY_CHECK;
01197     }
01198   ACE_CATCHANY
01199     {
01200       ACE_TRY_THROW (CosTrading::Register::UnknownTraderName (name));
01201     }
01202   ACE_ENDTRY;
01203   ACE_CHECK_RETURN (CosTrading::Register::_nil ());
01204 
01205   // Ensure that the register pointer isn't nil.
01206   if (! CORBA::is_nil (remote_reg.in ()))
01207     ACE_THROW_RETURN (CosTrading::Register::RegisterNotSupported (name),
01208                       CosTrading::Register::_nil ());
01209 
01210   CosTrading::Register_ptr return_value = remote_reg.in ();
01211 
01212   if (name.length () > 1)
01213     {
01214       // Create a new Trader Name with the first link removed.
01215       CosTrading::TraderName trader_name (name.length () - 1);
01216       for (int i = trader_name.length () - 1; i >= 0; i--)
01217         trader_name[i] = name[i + 1];
01218 
01219       return_value = remote_reg->resolve (trader_name ACE_ENV_ARG_PARAMETER);
01220       ACE_CHECK_RETURN (CosTrading::Register::_nil ());
01221     }
01222 
01223   return return_value;
01224 }
01225 
01226 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01227 void
01228 TAO_Register<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01229 validate_properties (const char* type,
01230                      const CosTradingRepos::ServiceTypeRepository::TypeStruct* type_struct,
01231                      const CosTrading::PropertySeq& properties
01232                      ACE_ENV_ARG_DECL)
01233   ACE_THROW_SPEC ((CosTrading::IllegalPropertyName,
01234                   CosTrading::PropertyTypeMismatch,
01235                   CosTrading::ReadonlyDynamicProperty,
01236                   CosTrading::MissingMandatoryProperty,
01237                   CosTrading::DuplicatePropertyName))
01238 {
01239   CORBA::ULong length = properties.length ();
01240   const CosTradingRepos::ServiceTypeRepository::PropStructSeq&
01241     prop_types = type_struct->props;
01242   TAO_Property_Evaluator_By_Name prop_eval (properties ACE_ENV_ARG_PARAMETER);
01243   ACE_CHECK;
01244 
01245   // Perform property validation
01246   length = prop_types.length ();
01247 
01248   for (CORBA::ULong i = 0; i < length; i++)
01249     {
01250       const CosTradingRepos::ServiceTypeRepository::PropStruct&
01251         prop_struct = prop_types[i];
01252       const char* prop_name  = prop_struct.name;
01253 
01254       // Obtain the type of the exported property.
01255       CORBA::TypeCode_var prop_type = prop_eval.property_type (prop_name);
01256 
01257       if (CORBA::is_nil (prop_type.in ()))
01258         {
01259           // Offer cannot have a missing mandatory property.
01260           if (prop_types[i].mode ==
01261               CosTradingRepos::ServiceTypeRepository::PROP_MANDATORY)
01262             ACE_THROW (CosTrading::MissingMandatoryProperty (type, prop_name));
01263         }
01264       else
01265         {
01266           int check =
01267             (! prop_type->equal (prop_struct.value_type.in ()
01268                                  ACE_ENV_ARG_PARAMETER));
01269           ACE_CHECK;
01270           if (check)
01271             {
01272               // Offer cannot redefine the type of an property.
01273               const CosTrading::Property* prop =
01274                 prop_eval.get_property (prop_name);
01275               ACE_THROW (CosTrading::PropertyTypeMismatch (type, *prop));
01276             }
01277           else if (prop_struct.mode ==
01278                    CosTradingRepos::ServiceTypeRepository::PROP_READONLY &&
01279                    prop_eval.is_dynamic_property (prop_name))
01280             ACE_THROW (CosTrading::ReadonlyDynamicProperty (type, prop_name));
01281         }
01282     }
01283 }
01284 
01285 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01286 TAO_Admin<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01287 TAO_Admin (TAO_Trader<TRADER_LOCK_TYPE,MAP_LOCK_TYPE> &trader)
01288   : TAO_Trader_Components <POA_CosTrading::Admin> (trader.trading_components ()),
01289     TAO_Support_Attributes <POA_CosTrading::Admin> (trader.support_attributes ()),
01290     TAO_Import_Attributes <POA_CosTrading::Admin> (trader.import_attributes ()),
01291     TAO_Link_Attributes <POA_CosTrading::Admin> (trader.link_attributes ()),
01292     trader_ (trader),
01293     sequence_number_ (0)
01294 {
01295   // A random 4-bytes will prefix the sequence number space for each
01296   // trader, making it extremely unlikely that the sequence spaces for
01297   // two traders will over lap.  @@ TODO: This is a bad way to
01298   // generate pseudo random numbers.
01299 
01300   // Ok, then, Carlos, we'll do it a different way: ip addr + pid.
01301   ACE_UINT32 ip_addr = 0;
01302   ACE_TCHAR host_name[BUFSIZ];
01303 
01304   if (ACE_OS::hostname (host_name,
01305                         BUFSIZ) != -1)
01306     {
01307       ACE_INET_Addr addr ((u_short) 0, host_name);
01308       ip_addr = addr.get_ip_address ();
01309     }
01310   // The better way to do unique stem identifiers.
01311   this->stem_id_.length (12);
01312 
01313   if (ip_addr != 0)
01314     {
01315       pid_t pid = ACE_OS::getpid ();
01316       this->stem_id_[0] = static_cast<CORBA::Octet> ((ip_addr >> 24) & 0xff);
01317       this->stem_id_[1] = static_cast<CORBA::Octet> ((ip_addr >> 16) & 0xff);
01318       this->stem_id_[2] = static_cast<CORBA::Octet> ((ip_addr >> 8) & 0xff);
01319       this->stem_id_[3] = static_cast<CORBA::Octet> (ip_addr & 0xff);
01320       this->stem_id_[4] = static_cast<CORBA::Octet> ((pid >> 24) & 0xff);
01321       this->stem_id_[5] = static_cast<CORBA::Octet> ((pid >> 16) & 0xff);
01322       this->stem_id_[6] = static_cast<CORBA::Octet> ((pid >> 8) & 0xff);
01323       this->stem_id_[7] = static_cast<CORBA::Octet> (pid & 0xff);
01324     }
01325 
01326   // The default way -- eight random integers.
01327   else
01328     {
01329       time_t time_value = ACE_OS::time ();
01330       ACE_OS::srand (static_cast<u_int> (time_value));
01331 
01332       this->stem_id_[0] = static_cast<CORBA::Octet> (ACE_OS::rand () %  256);
01333       this->stem_id_[1] = static_cast<CORBA::Octet> (ACE_OS::rand () %  256);
01334       this->stem_id_[2] = static_cast<CORBA::Octet> (ACE_OS::rand () %  256);
01335       this->stem_id_[3] = static_cast<CORBA::Octet> (ACE_OS::rand () %  256);
01336       this->stem_id_[4] = static_cast<CORBA::Octet> (ACE_OS::rand () %  256);
01337       this->stem_id_[5] = static_cast<CORBA::Octet> (ACE_OS::rand () %  256);
01338       this->stem_id_[6] = static_cast<CORBA::Octet> (ACE_OS::rand () %  256);
01339       this->stem_id_[7] = static_cast<CORBA::Octet> (ACE_OS::rand () %  256);
01340     }
01341 }
01342 
01343 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01344 TAO_Admin<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::~TAO_Admin (void)
01345 {
01346 }
01347 
01348 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01349 CosTrading::Admin::OctetSeq *
01350 TAO_Admin<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::request_id_stem (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
01351   ACE_THROW_SPEC ((CORBA::SystemException))
01352 {
01353   ACE_GUARD_RETURN (TRADER_LOCK_TYPE, trader_mon, this->lock_, 0);
01354 
01355   // Add one to the sequence_number and concatenate it to the unique
01356   // prefix. The sequence number is four octets long, the unique
01357   // prefix, also 4 bytes long.
01358 
01359   this->stem_id_[8] = static_cast<CORBA::Octet> (this->sequence_number_ & 0xff);
01360   this->stem_id_[9] = static_cast<CORBA::Octet> ((this->sequence_number_ >> 8) & 0xff);
01361   this->stem_id_[10] = static_cast<CORBA::Octet> ((this->sequence_number_ >> 16) & 0xff);
01362   this->stem_id_[11] = static_cast<CORBA::Octet> ((this->sequence_number_ >> 24) & 0xff);
01363 
01364   // Increment the sequence number and return a copy of the stem_id.
01365   this->sequence_number_++;
01366   return new CosTrading::Admin::OctetSeq (this->stem_id_);
01367 }
01368 
01369 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01370 CORBA::ULong
01371 TAO_Admin<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01372 set_def_search_card (CORBA::ULong value
01373                      ACE_ENV_ARG_DECL_NOT_USED )
01374   ACE_THROW_SPEC ((CORBA::SystemException))
01375 {
01376   CORBA::ULong return_value =
01377     this->trader_.import_attributes ().def_search_card ();
01378 
01379   this->trader_.import_attributes ().def_search_card (value);
01380   return return_value;
01381 }
01382 
01383 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01384 CORBA::ULong
01385 TAO_Admin<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01386 set_max_search_card (CORBA::ULong value
01387                      ACE_ENV_ARG_DECL_NOT_USED )
01388   ACE_THROW_SPEC ((CORBA::SystemException))
01389 {
01390   CORBA::ULong return_value =
01391     this->trader_.import_attributes ().max_search_card ();
01392 
01393   this->trader_.import_attributes ().max_search_card (value);
01394   return return_value;
01395 }
01396 
01397 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01398 CORBA::ULong
01399 TAO_Admin<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01400 set_def_match_card (CORBA::ULong value
01401                     ACE_ENV_ARG_DECL_NOT_USED )
01402   ACE_THROW_SPEC ((CORBA::SystemException))
01403 {
01404   CORBA::ULong return_value =
01405     this->trader_.import_attributes ().def_match_card ();
01406 
01407   this->trader_.import_attributes ().def_match_card (value);
01408   return return_value;
01409 }
01410 
01411 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01412 CORBA::ULong
01413 TAO_Admin<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01414 set_max_match_card (CORBA::ULong value
01415                     ACE_ENV_ARG_DECL_NOT_USED )
01416   ACE_THROW_SPEC ((CORBA::SystemException))
01417 {
01418   CORBA::ULong return_value =
01419     this->trader_.import_attributes ().max_match_card ();
01420 
01421   this->trader_.import_attributes ().max_match_card (value);
01422   return return_value;
01423 }
01424 
01425 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01426 CORBA::ULong
01427 TAO_Admin<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01428 set_def_return_card (CORBA::ULong value
01429                      ACE_ENV_ARG_DECL_NOT_USED )
01430   ACE_THROW_SPEC ((CORBA::SystemException))
01431 {
01432   CORBA::ULong return_value =
01433     this->trader_.import_attributes ().def_return_card ();
01434 
01435   this->trader_.import_attributes ().def_return_card (value);
01436   return return_value;
01437 }
01438 
01439 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01440 CORBA::ULong
01441 TAO_Admin<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01442 set_max_return_card (CORBA::ULong value
01443                      ACE_ENV_ARG_DECL_NOT_USED )
01444   ACE_THROW_SPEC ((CORBA::SystemException))
01445 {
01446   CORBA::ULong return_value =
01447     this->trader_.import_attributes ().max_return_card ();
01448 
01449   this->trader_.import_attributes ().max_return_card (value);
01450   return return_value;
01451 }
01452 
01453 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01454 CORBA::ULong
01455 TAO_Admin<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01456 set_max_list (CORBA::ULong value
01457               ACE_ENV_ARG_DECL_NOT_USED )
01458   ACE_THROW_SPEC ((CORBA::SystemException))
01459 {
01460   CORBA::ULong return_value =
01461     this->trader_.import_attributes ().max_list ();
01462 
01463   this->trader_.import_attributes ().max_list (value);
01464   return return_value;
01465 }
01466 
01467 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01468 CORBA::Boolean
01469 TAO_Admin<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01470 set_supports_modifiable_properties (CORBA::Boolean value
01471                                     ACE_ENV_ARG_DECL_NOT_USED )
01472   ACE_THROW_SPEC ((CORBA::SystemException))
01473 {
01474   CORBA::Boolean return_value =
01475     this->trader_.support_attributes ().supports_modifiable_properties ();
01476 
01477   this->trader_.support_attributes ().supports_modifiable_properties (value);
01478   return return_value;
01479 }
01480 
01481 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01482 CORBA::Boolean
01483 TAO_Admin<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01484 set_supports_dynamic_properties (CORBA::Boolean value
01485                                  ACE_ENV_ARG_DECL_NOT_USED )
01486   ACE_THROW_SPEC ((CORBA::SystemException))
01487 {
01488   CORBA::Boolean return_value =
01489     this->trader_.support_attributes ().supports_dynamic_properties ();
01490 
01491   this->trader_.support_attributes ().supports_dynamic_properties (value);
01492   return return_value;
01493 }
01494 
01495 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01496 CORBA::Boolean
01497 TAO_Admin<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01498 set_supports_proxy_offers (CORBA::Boolean value
01499                            ACE_ENV_ARG_DECL_NOT_USED )
01500   ACE_THROW_SPEC ((CORBA::SystemException))
01501 {
01502   CORBA::Boolean return_value =
01503     this->trader_.support_attributes ().supports_proxy_offers ();
01504 
01505   this->trader_.support_attributes ().supports_proxy_offers (value);
01506   return return_value;
01507 }
01508 
01509 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01510 CORBA::ULong
01511 TAO_Admin<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01512 set_def_hop_count (CORBA::ULong value
01513                    ACE_ENV_ARG_DECL_NOT_USED )
01514   ACE_THROW_SPEC ((CORBA::SystemException))
01515 {
01516   CORBA::ULong return_value =
01517     this->trader_.import_attributes ().def_hop_count ();
01518 
01519   this->trader_.import_attributes ().def_hop_count (value);
01520   return return_value;
01521 }
01522 
01523 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01524 CORBA::ULong
01525 TAO_Admin<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01526 set_max_hop_count (CORBA::ULong value
01527                    ACE_ENV_ARG_DECL_NOT_USED )
01528   ACE_THROW_SPEC ((CORBA::SystemException))
01529 {
01530   CORBA::ULong return_value =
01531     this->trader_.import_attributes ().max_hop_count ();
01532 
01533   this->trader_.import_attributes ().max_hop_count (value);
01534   return return_value;
01535 }
01536 
01537 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01538 CosTrading::FollowOption
01539 TAO_Admin<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01540 set_def_follow_policy (CosTrading::FollowOption policy
01541                        ACE_ENV_ARG_DECL_NOT_USED )
01542   ACE_THROW_SPEC ((CORBA::SystemException))
01543 {
01544   CosTrading::FollowOption return_value =
01545     this->trader_.import_attributes ().def_follow_policy ();
01546 
01547   this->trader_.import_attributes ().def_follow_policy (policy);
01548   return return_value;
01549 }
01550 
01551 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01552 CosTrading::FollowOption
01553 TAO_Admin<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01554 set_max_follow_policy (CosTrading::FollowOption policy
01555                        ACE_ENV_ARG_DECL_NOT_USED )
01556   ACE_THROW_SPEC ((CORBA::SystemException))
01557 {
01558   CosTrading::FollowOption return_value =
01559     this->trader_.import_attributes ().max_follow_policy ();
01560 
01561   this->trader_.import_attributes ().max_follow_policy (policy);
01562   return return_value;
01563 }
01564 
01565 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01566 CosTrading::FollowOption
01567 TAO_Admin<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01568 set_max_link_follow_policy (CosTrading::FollowOption policy
01569                             ACE_ENV_ARG_DECL_NOT_USED)
01570   ACE_THROW_SPEC ((CORBA::SystemException))
01571 {
01572   CosTrading::FollowOption return_value =
01573     this->trader_.link_attributes ().max_link_follow_policy ();
01574 
01575   this->trader_.link_attributes ().max_link_follow_policy (policy);
01576   return return_value;
01577 }
01578 
01579 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01580 CosTrading::TypeRepository_ptr
01581 TAO_Admin<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01582 set_type_repos (CosTrading::TypeRepository_ptr repository
01583                 ACE_ENV_ARG_DECL_NOT_USED)
01584   ACE_THROW_SPEC ((CORBA::SystemException))
01585 {
01586   CosTrading::TypeRepository_ptr return_value =
01587     this->trader_.support_attributes ().type_repos ();
01588 
01589   this->trader_.support_attributes ().type_repos (repository);
01590   return return_value;
01591 }
01592 
01593 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01594 CosTrading::Admin::OctetSeq*
01595 TAO_Admin<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01596 set_request_id_stem (const CosTrading::Admin::OctetSeq& stem
01597                        ACE_ENV_ARG_DECL_NOT_USED)
01598   ACE_THROW_SPEC ((CORBA::SystemException))
01599 {
01600   ACE_GUARD_RETURN (TRADER_LOCK_TYPE, trader_mon, this->lock_,
01601                     &this->stem_id_);
01602   this->stem_id_ = stem;
01603   return &this->stem_id_;
01604 }
01605 
01606 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01607 void
01608 TAO_Admin<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01609 list_offers (CORBA::ULong how_many,
01610              CosTrading::OfferIdSeq_out ids,
01611              CosTrading::OfferIdIterator_out id_itr
01612              ACE_ENV_ARG_DECL)
01613   ACE_THROW_SPEC ((CORBA::SystemException, CosTrading::NotImplemented))
01614 {
01615   // This method only applies when the register interface is implemented
01616   if (CORBA::is_nil (this->trader_.trading_components().register_if()))
01617     ACE_THROW (CosTrading::NotImplemented());
01618 
01619   TAO_Offer_Database<MAP_LOCK_TYPE>& type_map = this->trader_.offer_database ();
01620   TAO_Offer_Id_Iterator* offer_id_iter = type_map.retrieve_all_offer_ids ();
01621 
01622   id_itr = CosTrading::OfferIdIterator::_nil ();
01623   if (how_many > 0)
01624     {
01625       int check = offer_id_iter->next_n (how_many, ids ACE_ENV_ARG_PARAMETER);
01626       ACE_CHECK;
01627 
01628       if (check == 1)
01629         {
01630           id_itr = offer_id_iter->_this (ACE_ENV_SINGLE_ARG_PARAMETER);
01631           ACE_CHECK;
01632           offer_id_iter->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
01633           ACE_CHECK;
01634         }
01635       else
01636         delete offer_id_iter;
01637     }
01638   else
01639     ids = new CosTrading::OfferIdSeq (0);
01640 }
01641 
01642 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01643 void
01644 TAO_Admin<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01645 list_proxies (CORBA::ULong,
01646               CosTrading::OfferIdSeq_out,
01647               CosTrading::OfferIdIterator_out
01648               ACE_ENV_ARG_DECL)
01649   ACE_THROW_SPEC ((CORBA::SystemException,
01650                   CosTrading::NotImplemented))
01651 {
01652   ACE_THROW (CosTrading::NotImplemented ());
01653 }
01654 
01655 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01656 TAO_Link<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::TAO_Link (TAO_Trader<TRADER_LOCK_TYPE,MAP_LOCK_TYPE> &trader)
01657   : TAO_Trader_Components <POA_CosTrading::Link> (trader.trading_components ()),
01658     TAO_Support_Attributes <POA_CosTrading::Link> (trader.support_attributes ()),
01659     TAO_Link_Attributes <POA_CosTrading::Link> (trader.link_attributes ()),
01660     trader_ (trader)
01661 {
01662 }
01663 
01664 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01665 TAO_Link<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::~TAO_Link (void)
01666 {
01667 }
01668 
01669 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01670 void
01671 TAO_Link<TRADER_LOCK_TYPE, MAP_LOCK_TYPE>::
01672 add_link (const char *name,
01673           CosTrading::Lookup_ptr target,
01674           CosTrading::FollowOption def_pass_on_follow_rule,
01675           CosTrading::FollowOption limiting_follow_rule
01676           ACE_ENV_ARG_DECL)
01677   ACE_THROW_SPEC ((CORBA::SystemException,
01678                   CosTrading::Link::IllegalLinkName,
01679                   CosTrading::Link::DuplicateLinkName,
01680                   CosTrading::InvalidLookupRef,
01681                   CosTrading::Link::DefaultFollowTooPermissive,
01682                   CosTrading::Link::LimitingFollowTooPermissive))
01683 {
01684   // Ensure the link name is valid.
01685   if (! TAO_Trader_Base::is_valid_link_name (name))
01686     ACE_THROW (CosTrading::Link::IllegalLinkName (name));
01687 
01688   // Ensure this isn't a duplicate link name.
01689   CORBA::String_var link_name (name);
01690   if (this->links_.find (link_name) == 0)
01691     ACE_THROW (CosTrading::Link::DuplicateLinkName (name));
01692 
01693   // Ensure the lookup_ptr isn't nil.
01694   if (CORBA::is_nil (target))
01695     ACE_THROW (CosTrading::InvalidLookupRef (target));
01696 
01697   // Ensure that the default link behavior isn't stronger than the
01698   // limiting link behavior.
01699   if (def_pass_on_follow_rule > limiting_follow_rule)
01700     ACE_THROW (CosTrading::Link::DefaultFollowTooPermissive
01701                (def_pass_on_follow_rule, limiting_follow_rule));
01702 
01703   // Ensure that the limiting link behavior for this link doesn't
01704   // exceed the maximum allowed for a link.
01705   CosTrading::FollowOption follow_policy =
01706     this->max_link_follow_policy (ACE_ENV_SINGLE_ARG_PARAMETER);
01707   ACE_CHECK;
01708   if (limiting_follow_rule < follow_policy)
01709     ACE_THROW (CosTrading::Link::LimitingFollowTooPermissive
01710                (limiting_follow_rule, follow_policy));
01711 
01712   // Create a link info structure for this link of the federation.
01713   CosTrading::Link::LinkInfo link_info;
01714 
01715   link_info.target = CosTrading::Lookup::_duplicate (target);
01716 
01717   link_info.def_pass_on_follow_rule = def_pass_on_follow_rule;
01718   link_info.limiting_follow_rule = limiting_follow_rule;
01719   ACE_CHECK;
01720 
01721   // Insert this link into the collection of links.
01722   this->links_.bind (link_name, link_info);
01723 }
01724 
01725 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01726 void
01727 TAO_Link<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01728 remove_link (const char *name
01729              ACE_ENV_ARG_DECL)
01730   ACE_THROW_SPEC ((CORBA::SystemException,
01731                   CosTrading::Link::IllegalLinkName,
01732                   CosTrading::Link::UnknownLinkName))
01733 {
01734   // Ensure the link name is valid.
01735   if (! TAO_Trader_Base::is_valid_link_name (name))
01736     ACE_THROW (CosTrading::Link::IllegalLinkName (name));
01737 
01738   // Ensure this isn't a duplicate link name.
01739   CORBA::String_var link_name (name);
01740   if (this->links_.find (link_name) == -1)
01741     ACE_THROW (CosTrading::Link::UnknownLinkName (name));
01742 
01743   // Erase the link state from the map.
01744   this->links_.unbind (link_name);
01745 }
01746 
01747 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01748 CosTrading::Link::LinkInfo *
01749 TAO_Link<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::describe_link (const char *name
01750                                                ACE_ENV_ARG_DECL)
01751   ACE_THROW_SPEC ((CORBA::SystemException,
01752                    CosTrading::Link::IllegalLinkName,
01753                    CosTrading::Link::UnknownLinkName))
01754 {
01755   // Ensure the link name is valid.
01756   if (! TAO_Trader_Base::is_valid_link_name (name))
01757     ACE_THROW_RETURN (CosTrading::Link::IllegalLinkName (name), 0);
01758 
01759   // Ensure this isn't a duplicate link name.
01760   ACE_TYPENAME Links::ENTRY* link_entry = 0;
01761   CORBA::String_var link_name (name);
01762   if (this->links_.find (link_name, link_entry) == -1)
01763     ACE_THROW_RETURN (CosTrading::Link::UnknownLinkName (name),
01764                       0);
01765 
01766   // Build a new Link Info structure.
01767   CosTrading::Link::LinkInfo* new_link_info = 0;
01768   CosTrading::Link::LinkInfo& old_link_info = link_entry->int_id_;
01769 
01770   ACE_NEW_THROW_EX (new_link_info,
01771                     CosTrading::Link::LinkInfo,
01772                     CORBA::NO_MEMORY ());
01773   ACE_CHECK_RETURN (0);
01774 
01775   new_link_info->def_pass_on_follow_rule = old_link_info.def_pass_on_follow_rule;
01776   new_link_info->limiting_follow_rule = old_link_info.limiting_follow_rule;
01777 
01778   new_link_info->target = old_link_info.target;
01779 
01780   // Delayed retrieval of register interface.
01781   // This avoids the nested upcall that would occur were we to invoke
01782   // this method in the add_link method.
01783 
01784   new_link_info->target_reg = old_link_info.target->register_if (ACE_ENV_SINGLE_ARG_PARAMETER);
01785   ACE_CHECK_RETURN (new_link_info);
01786 
01787   // return the link information for this link name.
01788   return new_link_info;
01789 }
01790 
01791 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01792 CosTrading::LinkNameSeq*
01793 TAO_Link<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::list_links (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
01794   ACE_THROW_SPEC ((CORBA::SystemException))
01795 {
01796   // Allocate space for the link names.
01797   size_t size = this->links_.current_size ();
01798   CORBA::ULong i = 0;
01799   CosTrading::LinkName* link_seq =
01800     CosTrading::LinkNameSeq::allocbuf (static_cast<CORBA::ULong> (size));
01801 
01802   // Copy the link names into the buffer.
01803   for (ACE_TYPENAME Links::iterator links_iter (this->links_);
01804        ! links_iter.done ();
01805        links_iter++)
01806     link_seq[i++] = CORBA::string_dup ((*links_iter).ext_id_.in ());
01807 
01808   // Return a sequence of the buf names.
01809   return new CosTrading::LinkNameSeq (i, i, link_seq, 1);
01810 }
01811 
01812 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01813 void
01814 TAO_Link<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01815 modify_link (const char *name,
01816              CosTrading::FollowOption def_pass_on_follow_rule,
01817              CosTrading::FollowOption limiting_follow_rule
01818              ACE_ENV_ARG_DECL)
01819   ACE_THROW_SPEC ((CosTrading::Link::IllegalLinkName,
01820                    CosTrading::Link::UnknownLinkName,
01821                    CosTrading::Link::DefaultFollowTooPermissive,
01822                    CosTrading::Link::LimitingFollowTooPermissive))
01823 {
01824   // Ensure the link name is valid.
01825   if (! TAO_Trader_Base::is_valid_link_name (name))
01826     ACE_THROW (CosTrading::Link::IllegalLinkName (name));
01827 
01828   // Ensure this isn't a duplicate link name.
01829   ACE_TYPENAME Links::ENTRY* link_entry = 0;
01830   CORBA::String_var link_name (name);
01831   if (this->links_.find (link_name, link_entry) == -1)
01832     ACE_THROW (CosTrading::Link::UnknownLinkName (name));
01833 
01834   // Ensure that the default link behavior isn't stronger than the
01835   // limiting link behavior.
01836   if (def_pass_on_follow_rule > limiting_follow_rule)
01837     ACE_THROW (CosTrading::Link::DefaultFollowTooPermissive
01838                (def_pass_on_follow_rule, limiting_follow_rule));
01839 
01840   // Ensure that the limiting link behavior for this link doesn't
01841   // exceed the maximum allowed for a link.
01842   CosTrading::FollowOption follow_policy =
01843     this->max_link_follow_policy (ACE_ENV_SINGLE_ARG_PARAMETER);
01844   ACE_CHECK;
01845 
01846   if (limiting_follow_rule < follow_policy)
01847     ACE_THROW (CosTrading::Link::LimitingFollowTooPermissive
01848                (limiting_follow_rule, follow_policy));
01849 
01850   // Adjust the link settings
01851   CosTrading::Link::LinkInfo& link_info = link_entry->int_id_;
01852   link_info.def_pass_on_follow_rule = def_pass_on_follow_rule;
01853   link_info.limiting_follow_rule = limiting_follow_rule;
01854 }
01855 
01856 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01857 TAO_Proxy<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01858 TAO_Proxy (TAO_Trader<TRADER_LOCK_TYPE,MAP_LOCK_TYPE> &trader)
01859   : TAO_Trader_Components <POA_CosTrading::Proxy> (trader.trading_components ()),
01860     TAO_Support_Attributes <POA_CosTrading::Proxy> (trader.support_attributes ()),
01861     trader_ (trader)
01862 {
01863 }
01864 
01865 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01866 TAO_Proxy<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::~TAO_Proxy (void)
01867 {
01868 }
01869 
01870 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01871 CosTrading::OfferId
01872 TAO_Proxy<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01873 export_proxy (CosTrading::Lookup_ptr,
01874               const char *,
01875               const CosTrading::PropertySeq&,
01876               CORBA::Boolean,
01877               const char *,
01878               const CosTrading::PolicySeq&
01879               ACE_ENV_ARG_DECL)
01880   ACE_THROW_SPEC ((CORBA::SystemException,
01881                   CosTrading::IllegalServiceType,
01882                   CosTrading::UnknownServiceType,
01883                   CosTrading::InvalidLookupRef,
01884                   CosTrading::IllegalPropertyName,
01885                   CosTrading::PropertyTypeMismatch,
01886                   CosTrading::ReadonlyDynamicProperty,
01887                   CosTrading::MissingMandatoryProperty,
01888                   CosTrading::Proxy::IllegalRecipe,
01889                   CosTrading::DuplicatePropertyName,
01890                   CosTrading::DuplicatePolicyName))
01891 {
01892   ACE_THROW_RETURN (CORBA::UNKNOWN (), 0);
01893 
01894   return 0;
01895 }
01896 
01897 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01898 void
01899 TAO_Proxy<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01900 withdraw_proxy (const char *
01901                 ACE_ENV_ARG_DECL)
01902   ACE_THROW_SPEC ((CORBA::SystemException,
01903                   CosTrading::IllegalOfferId,
01904                   CosTrading::UnknownOfferId,
01905                   CosTrading::Proxy::NotProxyOfferId))
01906 {
01907   ACE_THROW (CORBA::UNKNOWN ());
01908 }
01909 
01910 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01911 CosTrading::Proxy::ProxyInfo *
01912 TAO_Proxy<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01913 describe_proxy (const char *
01914                 ACE_ENV_ARG_DECL)
01915   ACE_THROW_SPEC ((CORBA::SystemException,
01916                   CosTrading::IllegalOfferId,
01917                   CosTrading::UnknownOfferId,
01918                   CosTrading::Proxy::NotProxyOfferId))
01919 {
01920   ACE_THROW_RETURN (CORBA::UNKNOWN (), 0);
01921 
01922   return 0;
01923 }
01924 
01925 template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
01926 void
01927 TAO_Proxy<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
01928 list_proxies (CORBA::ULong,
01929               CosTrading::OfferIdSeq*&,
01930               CosTrading::OfferIdIterator_ptr&
01931               ACE_ENV_ARG_DECL)
01932   ACE_THROW_SPEC ((CORBA::SystemException,
01933                    CosTrading::NotImplemented))
01934 {
01935   ACE_THROW (CORBA::UNKNOWN ());
01936 }
01937 
01938 TAO_END_VERSIONED_NAMESPACE_DECL
01939 
01940 #endif /* TAO_TRADER_INTERFACES_CPP */

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