Trader_Interfaces.cpp

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

Generated on Tue Feb 2 17:49:26 2010 for TAO_CosTrader by  doxygen 1.4.7