📄 trader_interfaces.cpp
字号:
// Trader_Interfaces.cpp,v 1.59 2003/11/01 20:54:57 bala Exp
#if !defined (TAO_TRADER_INTERFACES_C)
#define TAO_TRADER_INTERFACES_C
#include "Trader_Interfaces.h"
#include "Trader_T.h"
#include "ace/INET_Addr.h"
#include "Trader_Constraint_Visitors.h"
#include "ace/OS_NS_time.h"
#include "ace/OS_NS_unistd.h"
ACE_RCSID(Trader, Trader_Interfaces, "Trader_Interfaces.cpp,v 1.59 2003/11/01 20:54:57 bala Exp")
template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
TAO_Lookup<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
TAO_Lookup (TAO_Trader<TRADER_LOCK_TYPE,MAP_LOCK_TYPE> &trader)
: TAO_Trader_Components<POA_CosTrading::Lookup> (trader.trading_components ()),
TAO_Support_Attributes<POA_CosTrading::Lookup> (trader.support_attributes ()),
TAO_Import_Attributes<POA_CosTrading::Lookup> (trader.import_attributes ()),
IDS_SAVED (100),
trader_ (trader)
{
}
template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
TAO_Lookup<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::~TAO_Lookup (void)
{
ACE_GUARD (TRADER_LOCK_TYPE, trader_mon, this->lock_);
for (Request_Ids::ITERATOR riter (this->request_ids_);
! riter.done ();
riter.advance ())
{
CosTrading::Admin::OctetSeq** old_seq = 0;
riter.next (old_seq);
delete *old_seq;
}
}
template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE> void
TAO_Lookup<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
query (const char *type,
const char *constraint,
const char *preferences,
const CosTrading::PolicySeq &in_policies,
const CosTrading::Lookup::SpecifiedProps &desired_props,
CORBA::ULong how_many,
CosTrading::OfferSeq_out returned_offers,
CosTrading::OfferIterator_out returned_offer_iterator,
CosTrading::PolicyNameSeq_out returned_limits_applied
ACE_ENV_ARG_DECL)
ACE_THROW_SPEC ((CORBA::SystemException,
CosTrading::IllegalServiceType,
CosTrading::UnknownServiceType,
CosTrading::IllegalConstraint,
CosTrading::Lookup::IllegalPreference,
CosTrading::Lookup::IllegalPolicyName,
CosTrading::Lookup::PolicyTypeMismatch,
CosTrading::Lookup::InvalidPolicyValue,
CosTrading::IllegalPropertyName,
CosTrading::DuplicatePropertyName,
CosTrading::DuplicatePolicyName))
{
// Instantiate a class to help interpret query policies.
TAO_Policies policies (this->trader_, in_policies ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
// If a federated query returns to us, ignore it to prevent
// redundant results and infinite loops.
CosTrading::Admin::OctetSeq* request_id = 0;
int check = this->seen_request_id (policies, request_id ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
if (check)
{
returned_offers = new CosTrading::OfferSeq;
returned_limits_applied = new CosTrading::PolicyNameSeq;
return;
}
// The presence of a link interface determines whether we should
// attempt to forward or propagate queries.
CosTrading::Link_ptr link_if =
this->trader_.trading_components ().link_if ();
// If the importer has specified a starting trader, foward the
// query.
CosTrading::TraderName* trader_name =
policies.starting_trader (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_CHECK;
if (! CORBA::is_nil (link_if) && trader_name != 0)
{
CosTrading::PolicySeq policies_to_forward;
policies.copy_to_forward (policies_to_forward, *trader_name);
const char* next_hop = (*trader_name)[0];
this->forward_query (next_hop,
type,
constraint,
preferences,
policies_to_forward,
desired_props,
how_many,
returned_offers,
returned_offer_iterator,
returned_limits_applied
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
return;
}
// Retrieve the type description struct from the Service Type Repos.
const TAO_Support_Attributes_i& support_attrs =
this->trader_.support_attributes ();
CosTradingRepos::ServiceTypeRepository_ptr rep =
support_attrs.service_type_repos ();
CosTradingRepos::ServiceTypeRepository::TypeStruct_var type_struct =
rep->fully_describe_type (type ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
// @@ Should throw a NO_MEMORY exception here...
ACE_NEW (returned_offers,
CosTrading::OfferSeq);
// Obtain a reference to the offer database.
TAO_Offer_Database<MAP_LOCK_TYPE>& offer_database =
this->trader_.offer_database ();
// TAO_Offer_Filter -- ensures that we don't consider offers with
// modifiable or dynamic properties if the Trader doesn't support
// them, or the importer has turned them off using policies.
// TAO_Constraint_Validator -- validates the constraint with the
// property types in the supplied type. TAO_Constraint_Interpreter
// -- parses the constraint string, and determines whether an offer
// meets those constraints. TAO_Preference_Interpreter -- parses
// the preference string and orders offers according to those
// constraints.
TAO_Offer_Filter offer_filter (policies
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
TAO_Trader_Constraint_Validator validator (type_struct.in ());
TAO_Constraint_Interpreter constr_inter (validator,
constraint
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
TAO_Preference_Interpreter pref_inter (validator,
preferences
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
// Try to find the map of offers of desired service type.
offer_filter.configure_type (type_struct.ptr ());
this->lookup_one_type (type,
offer_database,
constr_inter,
pref_inter,
offer_filter);
CORBA::Boolean result = policies.exact_type_match (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_CHECK;
if (!result)
{
// If the importer hasn't demanded an exact match search, we
// search all the subtypes of the supplied type. NOTE: Only the
// properties belonging to the provided type are considered on
// subtypes. Additional properties on the subtype are generally
// ignored. This is as it should be, consistent with the notions
// of type inheritence.
this->lookup_all_subtypes (type,
type_struct->incarnation,
offer_database,
rep,
constr_inter,
pref_inter,
offer_filter
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
}
// Take note of the limits applied in this query.
returned_limits_applied = offer_filter.limits_applied ();
// Fill the return sequence and iterator with the bountiful results.
CORBA::ULong offers_returned =
this->fill_receptacles (type,
how_many,
desired_props,
policies,
pref_inter,
*returned_offers.ptr (),
returned_offer_iterator
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
// The following steps are only appropriate for a linked trader.
if (! CORBA::is_nil (link_if))
{
// Determine if we should perform a federated query, and if so
// construct a sequence of links to follow.
CosTrading::LinkNameSeq_var links;
CORBA::Boolean should_follow =
this->retrieve_links (policies,
offers_returned,
CosTrading::LinkNameSeq_out (links.out ())
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
if (should_follow && links->length () != 0)
{
// Query those links we've accumulated!
this->federated_query (links.in (),
policies,
*request_id,
pref_inter,
type,
constraint,
preferences,
desired_props,
how_many,
*returned_offers.ptr (),
returned_offer_iterator.ptr (),
*returned_limits_applied.ptr ()
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
}
}
}
template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
void
TAO_Lookup<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
lookup_one_type (const char* type,
TAO_Offer_Database<MAP_LOCK_TYPE>& offer_database,
TAO_Constraint_Interpreter& constr_inter,
TAO_Preference_Interpreter& pref_inter,
TAO_Offer_Filter& offer_filter)
{
// Retrieve an iterator over the offers for a given type.
// @@ Would have used Offer_Database::offer_iterator for less
// coupling between TAO_Lookup and Offer_Database, but g++ barfs on
// that.
#if defined(_MSC_VER)
TAO_Offer_Database<MAP_LOCK_TYPE>::offer_iterator
offer_iter (type, offer_database);
#else
// MSVC won't grok this for some reason, but it's necessary for the
// HP compiler, which seriously requires the typename keyword
// here. I apologize if this ifdef offends some ACE users'
// sensibilities --- it certainly offends mine.
ACE_TYPENAME TAO_Offer_Database<MAP_LOCK_TYPE>::offer_iterator
offer_iter (type, offer_database);
#endif
while (offer_filter.ok_to_consider_more () &&
offer_iter.has_more_offers ())
{
// For each offer in the iterator, attempt to match it with
// the constraints passed to the Query method. If it matches
// the constraint, use the TAO_Preference_Interpreter to
// order the matched offers with respect to the preference
// string passed to the method. All the while the offer
// filter ensures we don't exceed the match cardinality
// constraints.
CosTrading::Offer* offer = offer_iter.get_offer ();
TAO_Trader_Constraint_Evaluator evaluator (offer);
if (offer_filter.ok_to_consider (offer) &&
constr_inter.evaluate (evaluator))
{
// Shove the offer and its id into the preference
// ordering object, pref_inter.
CosTrading::OfferId offer_id = offer_iter.get_id ();
pref_inter.order_offer (evaluator, offer, offer_id);
offer_filter.matched_offer ();
}
offer_iter.next_offer ();
}
}
template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
void
TAO_Lookup<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
lookup_all_subtypes (const char* type,
CosTradingRepos::ServiceTypeRepository::IncarnationNumber& inc_num,
TAO_Offer_Database<MAP_LOCK_TYPE>& offer_database,
CosTradingRepos::ServiceTypeRepository_ptr rep,
TAO_Constraint_Interpreter& constr_inter,
TAO_Preference_Interpreter& pref_inter,
TAO_Offer_Filter& offer_filter
ACE_ENV_ARG_DECL)
{
// BEGIN SPEC
// The trader may return a service offer of a subtype of the "type"
// requested. Sub-typing of service types is discussed in "Service
// Types" on page 16-4. A service subtype can be described by the
// properties of its supertypes. This ensures that a well-formed query
// for the "type" is also a well-formed query with respect to any
// subtypes. However, if the importer specifies the policy of
// exact_type_match = TRUE, then only offers with the exact (no
// subtype) service type requested are returned.
// END SPEC
CosTradingRepos::ServiceTypeRepository::SpecifiedServiceTypes sst;
CosTradingRepos::ServiceTypeRepository::ServiceTypeNameSeq_var all_types;
// Optimization: Since a subtype can't have a higher incarnation
// number than a supertype, we don't need to consider those
// types with lower incarnation numbers.
sst.incarnation (inc_num);
all_types = rep->list_types (sst ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
// Scan all types inserted after the super types. If the transitive
// closure of a type's super type relation includes the super type
// being considered, then perform a search on that type.
CORBA::ULong num_types = all_types->length ();
CosTradingRepos::ServiceTypeRepository::TypeStruct_var type_struct;
for (CORBA::ULong i = 0;
i < num_types && offer_filter.ok_to_consider_more ();
i++)
{
// Obtain a description of the prospective type.
type_struct = rep->fully_describe_type (all_types[i]
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
CosTradingRepos::ServiceTypeRepository::ServiceTypeNameSeq&
super_types = type_struct->super_types;
CORBA::ULong num_super_types = super_types.length ();
for (CORBA::ULong j = 0; j < num_super_types; j++)
{
if (ACE_OS::strcmp (type_struct->super_types[j], type) == 0)
{
// Egads, a subtype! This type has the type passed
// to query in its list of super_types.
offer_filter.configure_type (type_struct.ptr ());
this->lookup_one_type (all_types[i],
offer_database,
constr_inter,
pref_inter,
offer_filter);
break;
}
}
}
}
template <class TRADER_LOCK_TYPE, class MAP_LOCK_TYPE>
int
TAO_Lookup<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::
fill_receptacles (const char* /* type */,
CORBA::ULong how_many,
const CosTrading::Lookup::SpecifiedProps& desired_props,
TAO_Policies& policies,
TAO_Preference_Interpreter& pref_inter,
CosTrading::OfferSeq& offers,
CosTrading::OfferIterator_ptr& offer_itr
ACE_ENV_ARG_DECL)
ACE_THROW_SPEC ((CosTrading::IllegalPropertyName,
CosTrading::DuplicatePropertyName))
{
// BEGIN SPEC
// The returned offers are passed back in one of two ways (or a
// combination of both).
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -