KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jacorb > trading > impl > LookupImpl


1
2 // Copyright (C) 1998-1999
3
// Object Oriented Concepts, Inc.
4

5 // **********************************************************************
6
//
7
// Copyright (c) 1997
8
// Mark Spruiell (mark@intellisoft.com)
9
//
10
// See the COPYING file for more information
11
//
12
// **********************************************************************
13

14 package org.jacorb.trading.impl;
15
16 import java.util.*;
17
18 import org.apache.avalon.framework.logger.*;
19 import org.apache.avalon.framework.configuration.*;
20
21
22 import org.omg.CORBA.*;
23 import org.omg.CosTrading.*;
24 import org.omg.CosTrading.LookupPackage.*;
25 import org.omg.CosTrading.RegisterPackage.OfferInfo;
26 import org.omg.CosTrading.ProxyPackage.ProxyInfo;
27 import org.omg.CosTrading.LinkPackage.LinkInfo;
28 import org.omg.CosTradingRepos.*;
29 import org.omg.CosTradingRepos.ServiceTypeRepositoryPackage.*;
30
31 import org.jacorb.trading.constraint.*;
32 import org.jacorb.trading.db.OfferDatabase;
33 import org.jacorb.trading.util.*;
34 import org.jacorb.config.Configuration;
35
36 /**
37  * Implementation of CosTrading::Lookup
38  */

39
40 public class LookupImpl
41     extends org.omg.CosTrading.LookupPOA
42 {
43     private TraderComp m_traderComp;
44     private SupportAttrib m_support;
45     private ImportAttrib m_import;
46     private OfferDatabase m_db;
47     private ServiceTypeRepository m_repos;
48
49     //////////////////////////////////////////////////////////////// new!
50
private LinkImpl m_link_if; // for efficient access to the links
51
private static int m_query_counter; // suffix for request_id
52
private Hashtable m_query_cache_lookup; // efficient lookup of request_ids
53
private Vector m_query_cache_queue; // efficient removal of old queries
54
private int m_query_cache_max = 100; //max no. of queries to be cached
55
private QueryPropagator m_query_distrib; // threadpool for concurrent query distribution
56
private LinkInfo[] m_links_cache; // array of federated traders
57

58     private static int count = 0;
59     private Logger logger;
60
61     //////////////////////////////////////////////////////////////// new!
62
private LookupImpl()
63     {
64     }
65
66
67     public LookupImpl(TraderComp traderComp,
68               SupportAttrib supportAttrib,
69               ImportAttrib importAttrib,
70               OfferDatabase db,
71               LinkImpl link,
72                       org.jacorb.config.Configuration config)
73     {
74     m_traderComp = traderComp;
75     m_support = supportAttrib;
76     m_import = importAttrib;
77     m_db = db;
78     org.omg.CORBA.Object JavaDoc obj = supportAttrib.getTypeRepos();
79     m_repos = ServiceTypeRepositoryHelper.narrow(obj);
80         this.logger = config.getNamedLogger("jacorb.trading");
81         this.m_query_cache_max = config.getAttributeAsInteger("jtrader.impl.cache_max",100);
82
83     //////////////////////////////////////////////////////////////// new!
84
m_link_if = link;
85
86     // standard load factor of Hashtable is 0.75, so if we want to store efficiently
87
// m_query_cache_max elements, we have to account for the load factor.
88
// The +10 is just a safety margin.
89
m_query_cache_lookup = new Hashtable((int) ((100.0 / 75.0) * (double) m_query_cache_max) + 10);
90     m_query_cache_queue = new Vector(m_query_cache_max + 2);
91
92     m_query_distrib = new QueryPropagator();
93         try
94         {
95             m_query_distrib.configure(config);
96         }
97         catch( ConfigurationException ce )
98         {
99             logger.error("ConfigurationException", ce );
100             throw new org.omg.CORBA.INITIALIZE JavaDoc(ce.getMessage());
101         }
102     }
103
104
105     /**
106      * Overridden from Visibroker's _LookupImplBase; we do this instead
107      * of the unportable super("TradingService") we'd have to put in
108      * the constructor; the presence of this method should not affect
109      * use with other ORBs
110      */

111     public String JavaDoc _object_name()
112     {
113     return "TradingService";
114     }
115
116
117     // operations inherited from CosTrading::TraderComponents
118

119     public Lookup lookup_if()
120     {
121     return m_traderComp.getLookupInterface();
122     }
123
124
125     public Register register_if()
126     {
127     return m_traderComp.getRegisterInterface();
128     }
129
130
131     public Link link_if()
132     {
133     return m_traderComp.getLinkInterface();
134     }
135
136
137     public Proxy proxy_if()
138     {
139     return m_traderComp.getProxyInterface();
140     }
141
142
143     public Admin admin_if()
144     {
145     return m_traderComp.getAdminInterface();
146     }
147
148
149     // operations inherited from CosTrading::SupportAttributes
150

151     public boolean supports_modifiable_properties()
152     {
153     return m_support.getModifiableProperties();
154     }
155
156
157     public boolean supports_dynamic_properties()
158     {
159     return m_support.getDynamicProperties();
160     }
161
162
163     public boolean supports_proxy_offers()
164     {
165     return m_support.getProxyOffers();
166     }
167
168
169     public org.omg.CORBA.Object JavaDoc type_repos()
170     {
171     return m_support.getTypeRepos();
172     }
173
174
175     // operations inherited from CosTrading::SupportAttributes
176

177
178     public int def_search_card()
179     {
180     return m_import.getDefSearchCard();
181     }
182
183
184     public int max_search_card()
185     {
186     return m_import.getMaxSearchCard();
187     }
188
189
190     public int def_match_card()
191     {
192     return m_import.getDefMatchCard();
193     }
194
195
196     public int max_match_card()
197     {
198     return m_import.getMaxMatchCard();
199     }
200
201
202     public int def_return_card()
203     {
204     return m_import.getDefReturnCard();
205     }
206
207
208     public int max_return_card()
209     {
210     return m_import.getMaxReturnCard();
211     }
212
213
214     public int max_list()
215     {
216     return m_import.getMaxList();
217     }
218
219
220     public int def_hop_count()
221     {
222     return m_import.getDefHopCount();
223     }
224
225
226     public int max_hop_count()
227     {
228     return m_import.getMaxHopCount();
229     }
230
231
232     public FollowOption def_follow_policy()
233     {
234     return m_import.getDefFollowPolicy();
235     }
236
237
238     public FollowOption max_follow_policy()
239     {
240     return m_import.getMaxFollowPolicy();
241     }
242
243
244
245     // operations inherited from CosTrading::Lookup
246

247     public void query(String JavaDoc type,
248               String JavaDoc constr,
249               String JavaDoc pref,
250               org.omg.CosTrading.Policy[] policies,
251               SpecifiedProps desired_props,
252               int how_many,
253               OfferSeqHolder offers,
254               OfferIteratorHolder offer_itr,
255               PolicyNameSeqHolder limits_applied)
256     throws IllegalServiceType,
257     UnknownServiceType,
258     IllegalConstraint,
259     IllegalPreference,
260     IllegalPolicyName,
261     PolicyTypeMismatch,
262     InvalidPolicyValue,
263     IllegalPropertyName,
264     DuplicatePropertyName,
265     DuplicatePolicyName
266     {
267     int no = count++;
268
269     // retrieve complete information about the service type from the
270
// repository - may throw IllegalServiceType, UnknownServiceType
271
TypeStruct ts = m_repos.fully_describe_type(type);
272
273     // build a hashtable of the policies
274
Hashtable policyTable = new Hashtable();
275     for (int i = 0; i < policies.length; i++)
276     {
277         // check for duplicates
278
if (policyTable.containsKey(policies[i].name))
279         throw new DuplicatePolicyName(policies[i].name);
280         policyTable.put(policies[i].name, policies[i].value);
281     }
282
283     // check request_id
284
// request_id set?
285
String JavaDoc _id = getPolicyValue(policyTable, "request_id", new String JavaDoc());
286     Vector _generated_policies = new Vector();
287
288     if (_id.length() == 0)
289     {
290         // no request_id set, so we're the first to receive this offer
291
//generating new one
292
StringBuffer JavaDoc _new_id = new StringBuffer JavaDoc(new String JavaDoc(admin_if().request_id_stem()));
293         _new_id.append(m_query_counter++);
294         org.omg.CosTrading.Policy _id_policy = new org.omg.CosTrading.Policy();
295         _id_policy.name = "request_id";
296         _id_policy.value = _orb().create_any();
297         _id_policy.value.insert_string(_new_id.toString());
298
299         _generated_policies.addElement(_id_policy);
300         _id = _new_id.toString();
301     }
302
303     //don't process query, if we did already
304
if (queryAlreadyEncountered(_id))
305     {
306         // initializing anyway so we don't run into NullPointerEcxecptions
307
offers.value = new Offer[0];
308         limits_applied.value = new String JavaDoc[0];
309         return;
310     }
311
312     // if hop_count policy not set, we generate one from the defaults
313
if (! policyTable.containsKey("hop_count"))
314     {
315         org.omg.CosTrading.Policy _hop_policy = new org.omg.CosTrading.Policy();
316         _hop_policy.name = "hop_count";
317         _hop_policy.value = _orb().create_any();
318         _hop_policy.value.insert_ulong(def_hop_count());
319     
320         _generated_policies.addElement(_hop_policy);
321         policyTable.put("hop_count", _hop_policy.value);
322     }
323
324     // if we have generated new policies, we merge them with the existing ones
325
if (_generated_policies.size() > 0)
326     {
327         org.omg.CosTrading.Policy[] _new_policies =
328                 new org.omg.CosTrading.Policy[policies.length +
329                                               _generated_policies.size()];
330         System.arraycopy(policies, 0, _new_policies, 0, policies.length);
331
332         Enumeration _gen_polic_enum = _generated_policies.elements();
333         int _j = policies.length;
334         while(_gen_polic_enum.hasMoreElements())
335         _new_policies[_j++] = (org.omg.CosTrading.Policy) _gen_polic_enum.nextElement();
336     
337         policies = _new_policies;
338     }
339
340
341     // determine our limiting policies
342
int searchCard = getPolicyValue(policyTable, "search_card",
343                     def_search_card(), max_search_card());
344     int matchCard = getPolicyValue(policyTable, "match_card",
345                        def_match_card(), max_match_card());
346     int returnCard = getPolicyValue(policyTable, "return_card",
347                     def_return_card(), max_return_card());
348     boolean exactType = getPolicyValue(policyTable, "exact_type_match", false);
349   
350     // importer cannot override use_dynamic_properties if the
351
// trader doesn't support it
352
boolean useDynamic;
353     if (supports_dynamic_properties() == false)
354         useDynamic = false;
355     else
356         useDynamic =
357         getPolicyValue(policyTable, "use_dynamic_properties", true);
358
359     // importer cannot override use_modifiable_properties if the
360
// trader doesn't support it
361
boolean useModifiable;
362     if (supports_modifiable_properties() == false)
363         useModifiable = false;
364     else
365         useModifiable =
366         getPolicyValue(policyTable, "use_modifiable_properties", true);
367
368     // importer cannot override use_proxy_offers if the
369
// trader doesn't support it
370
boolean useProxyOffers;
371     if (supports_proxy_offers() == false)
372         useProxyOffers = false;
373     else
374         useProxyOffers = getPolicyValue(policyTable, "use_proxy_offers", true);
375
376     //////////////////////////////////////////////////////////////// new!
377
//determine link_follow_rule
378
FollowOption link_follow_rule = getPolicyValue(policyTable, "link_follow_rule",
379                                def_follow_policy(),
380                                max_follow_policy());
381     // determine hop count
382
int hop_count = getPolicyValue(policyTable, "hop_count", def_hop_count(), max_hop_count());
383
384     //decrement hop_count for query distribution
385
Any _hop = (Any) policyTable.get("hop_count");
386     _hop.insert_ulong(_hop.extract_ulong() - 1);
387
388
389     //////////////////////////////////////////////////////////////// new!
390
// starting query distribution here, since if we have illegal constraints,
391
// we don't have to distribute.
392
QueryContainer _templ = new QueryContainer(type,constr, pref,
393                            policies, desired_props,
394                            how_many, null);
395     Vector _queries = new Vector();
396
397     // if link_follow_rule is always, we don't find offers offers locally, and we
398
// have links with limiting_follow_rule if_no_local and always, we don't want
399
// to use the links with always again
400
Hashtable _used_links = new Hashtable();
401
402     if (hop_count > 0 &&
403         link_follow_rule.value() == FollowOption.always.value())
404         distributeQuery(_queries, _templ, link_follow_rule, _used_links);
405
406     //////////////////////////////////////////////////////////////// new!
407

408     // if no preference is supplied, "first" is the default
409
if (pref == null || pref.trim().length() == 0)
410         pref = "first";
411
412     // instantiate the schema object required by the parsers
413
SchemaAdapter schema = new SchemaAdapter(ts);
414
415     Constraint constraint = new Constraint(schema);
416     Preference preference = new Preference(schema);
417
418     try {
419         // attempt to parse the constraint
420
constraint.parse(constr);
421     }
422     catch (ParseException ex) {
423         // the exception doesn't include a reason, so we just print it
424
System.out.println("Illegal constraint '" + constr + "'");
425         System.out.println(ex.getMessage());
426         throw new IllegalConstraint(constr);
427     }
428
429     try {
430         // attempt to parse the preference
431
preference.parse(pref);
432     }
433     catch (ParseException ex) {
434         // the exception doesn't include a reason, so we just print it
435
System.out.println("Illegal preference '" + pref + "'");
436         System.out.println(ex.getMessage());
437         throw new IllegalPreference(pref);
438     }
439
440
441     // compose a list of all the service types we will consider;
442
// we start with just the type specified
443
Vector types = new Vector();
444     types.addElement(type);
445
446     // if the client wishes us to consider subtypes, then we need to
447
// find all service types "compatible" with the requested type
448
// (i.e. the type itself, and any subtypes)
449
if (! exactType)
450         findCompatibleTypes(type, types);
451
452     try {
453         m_db.begin(OfferDatabase.READ);
454
455         // iterate through all of the selected service types, examining
456
// the offers of each, and adding any potential ones to
457
// potentialOffers while respecting the search cardinality limits
458
int searchCount = 0;
459         Vector potentialOffers = new Vector();
460         Enumeration e = types.elements();
461  
462         while (e.hasMoreElements() && searchCount < searchCard)
463         {
464         String JavaDoc typeName = (String JavaDoc)e.nextElement();
465         Hashtable table = m_db.getOffers(typeName);
466         if (table == null)
467             continue;
468  
469         // examine the offers of this service type
470
Enumeration o = table.elements();
471         while (o.hasMoreElements() && searchCount < searchCard)
472         {
473             OfferInfo info = (OfferInfo)o.nextElement();
474
475             SourceAdapter source =
476             new SourceAdapter(info.reference, info.properties);
477
478             if (considerOffer(source, useDynamic, useModifiable, ts)) {
479             potentialOffers.addElement(source);
480             searchCount++;
481             }
482         }
483         }
484
485         // iterate through all of the selected service types, examining
486
// the proxy offers of each, and adding any potential ones to
487
// potentialOffers while respecting the search cardinality limits
488
if (useProxyOffers) {
489         e = types.elements();
490         while (e.hasMoreElements() && searchCount < searchCard)
491         {
492             String JavaDoc typeName = (String JavaDoc)e.nextElement();
493             Hashtable table = m_db.getProxyOffers(typeName);
494             if (table == null)
495             continue;
496
497             // examine the offers of this service type
498
Enumeration o = table.elements();
499             while (o.hasMoreElements() && searchCount < searchCard)
500             {
501             ProxyInfo info = (ProxyInfo)o.nextElement();
502
503             ProxySourceAdapter source = new ProxySourceAdapter(info);
504
505             if (considerOffer(source, useDynamic, useModifiable, ts)) {
506                 potentialOffers.addElement(source);
507                 searchCount++;
508             }
509             }
510         }
511         }
512  
513         // this object is used to evaluate offers
514
OfferEvaluator eval = new OfferEvaluator(type, constraint, pref,
515                              policies, desired_props, potentialOffers, matchCard);
516
517         // retrieve the results of the offer evaluation;
518
// this will block until all offers have been evaluated or
519
// until the match cardinality limits are reached; the
520
// matchingOffers vector contains only SourceAdapter objects
521
// (i.e. no ProxySourceAdapter objects)
522
Vector matchingOffers = eval.getResults();
523  
524
525         //////////////////////////////////////////////////////////////// new!
526
// if we didn't get any matching offers locally, we try to fetch them
527
// via the federation
528
if ( matchingOffers.size() == 0 && hop_count > 0 &&
529          link_follow_rule.value() >= FollowOption.if_no_local.value())
530         distributeQuery(_queries, _templ, link_follow_rule, _used_links);
531
532         // processing distributed queries and merging them with local offers
533
Enumeration _results = _queries.elements();
534         Vector _dropped = new Vector();
535
536         // for collecting the applied_policies of the distributed queries
537
Vector _applied_policies = new Vector();
538
539         while (_results.hasMoreElements()){
540         QueryContainer _distrib_query = (QueryContainer) _results.nextElement();
541         try{
542             _distrib_query.resultReady(); //blocks until remote query returned
543
}catch(Exception JavaDoc _e){
544                     _e.printStackTrace();
545             continue; // possibly InterruptedException, dropping this result
546
}
547       
548         UserException _query_exception = _distrib_query.getException();
549         if (_query_exception != null){
550             _dropped.addElement(_distrib_query);
551             continue; // an exception occured during distributed query execution,
552
// dropping this result
553
}
554
555         // get offers
556
OfferSeqHolder _offers = _distrib_query.getOffers();
557         if (_offers.value == null || _offers.value.length == 0){
558             // possibly loop-prevention refused to execute query
559
_dropped.addElement(_distrib_query);
560             continue;
561         }
562
563         // this is a little odd on the second look, since the local offers are
564
// stored as SourceAdapters, and we insert Offers, but its easier for
565
// determining the total amount of results
566
for (int i = 0; i < _offers.value.length; i++)
567             matchingOffers.addElement(_offers.value[i]);
568
569         // get limits_applied
570
PolicyNameSeqHolder _policy_holder = _distrib_query.getLimits();
571         if (_policy_holder.value != null){
572             // merging applied_policies with the others
573
for (int i = 0; i < _policy_holder.value.length; i++)
574             _applied_policies.addElement(_policy_holder.value[i]);
575         }
576         }
577         for (int _i = 0; _i < _dropped.size(); _i++)
578         _queries.removeElement(_dropped.elementAt(_i));
579       
580         //////////////////////////////////////////////////////////////// new!
581

582         int matchCount = matchingOffers.size();
583       
584         // order the matching offers using the preference
585
Vector orderedOffers = preference.order(matchingOffers);
586
587         // process the offers
588
int returnCount = Math.min(matchCount, returnCard);
589         int seqCount = Math.min(returnCount, how_many);
590
591         offers.value = new Offer[seqCount];
592         int count = 0;
593         e = orderedOffers.elements();
594         while (e.hasMoreElements() && count < seqCount) {
595         java.lang.Object JavaDoc _element = e.nextElement();
596         if (_element instanceof Offer){
597             offers.value[count] = (Offer) _element;
598             // this offer was retrieved from a federated trader
599
}
600         else{
601             SourceAdapter src = (SourceAdapter) _element;
602             offers.value[count] = new Offer();
603             offers.value[count].reference = src.getObject();
604             offers.value[count].properties = src.getProperties(desired_props);
605         }
606         count++;
607         }
608
609         // construct an iterator if necessary
610
if (seqCount < returnCount) {
611         // create a sequence holding the remaining offers
612
int restCount = returnCount - seqCount;
613         Vector rest = new Vector(restCount);
614       
615         int pos = 0;
616         while (e.hasMoreElements() && pos < restCount) {
617             java.lang.Object JavaDoc _element = e.nextElement();
618             if (_element instanceof Offer){
619             // this offer was retrieved from a federated trader
620
rest.addElement(_element);
621             }
622             else{
623             SourceAdapter src = (SourceAdapter)_element;
624             Offer _off = new Offer();
625             _off.reference = src.getObject();
626             _off.properties = src.getProperties(desired_props);
627             rest.addElement(_off);
628             }
629             pos++;
630         }
631     
632         //////////////////////////////////////////////////////////////// new!
633
// get iterator-based offers
634
_results = _queries.elements();
635         while (pos < restCount && _results.hasMoreElements()){
636             pos++;
637             QueryContainer _distrib_query = (QueryContainer) _results.nextElement();
638             OfferIteratorHolder _itr_holder = _distrib_query.getItr();
639             if (_itr_holder.value != null){
640             Offer[] _offers = null;
641             try{
642                 _offers = ((OfferIteratorImpl) _itr_holder.value).getOffers();
643                 // if we have an OfferIteratorImpl, we can simply obtain
644
// a reference to its Offers-Array
645
}catch(Exception JavaDoc _e){
646                 // possibly the OfferIterator wasn't an OfferIteratorImpl
647
}
648             if (_offers == null){
649                 // no OfferIteratorImpl-Instance, so we have to
650
// do it the hard way
651
OfferIterator _itr = _itr_holder.value;
652                 OfferSeqHolder _seq = new OfferSeqHolder();
653                 _itr.next_n(restCount - pos, _seq); // just one call with as much
654
// as possible offers
655
_offers = _seq.value;
656             }
657
658             // copy array into vector
659
int _i = 0;
660             while (_i < _offers.length && pos < restCount){
661                 pos++;
662                 rest.addElement(_offers[_i++]);
663             }
664             }
665         }
666
667         // build offer-array from vector
668
Enumeration _offer_enum = rest.elements();
669         Offer[] _offer_array = new Offer[rest.size()];
670         int _i = 0;
671         while (_offer_enum.hasMoreElements())
672             _offer_array[_i++] = (Offer) _offer_enum.nextElement();
673           
674         // set up Iterator
675
OfferIteratorImpl iter = new OfferIteratorImpl(_offer_array, 0);
676         iter._this_object( _orb() );
677         offer_itr.value = iter._this();
678
679         }
680
681         // build array of applied_limits from vector
682
Enumeration _applied_limits = _applied_policies.elements();
683         limits_applied.value = new String JavaDoc[_applied_policies.size()];
684         int _i = 0;
685         while (_applied_limits.hasMoreElements())
686         limits_applied.value[_i++] = (String JavaDoc) _applied_limits.nextElement();
687
688     }
689     finally {
690         m_db.end();
691     }
692
693     }
694
695
696     //////////////////////////////////////////////////////////////// new!
697
/**
698      * This is the loop-prevention mechanism. It checks the request_id-policy
699      * if this query was recently already encountered. If not so, the id
700      * is stored. <br>
701      * Using a Hashtable *and* a Vector since lookup is slow in a Vector,
702      * but a Hashtable has no method to get an element without a key (i.e
703      * the first).
704      *
705      * @param id The request_id
706      * @return True, if query was recently encountered
707      */

708     private boolean queryAlreadyEncountered (String JavaDoc id){
709
710     boolean _id_known = m_query_cache_lookup.containsKey(id);
711     if (! _id_known){
712         // inserting this one
713
m_query_cache_lookup.put(id, id);
714         m_query_cache_queue.addElement(id);
715         
716         // removing the oldest
717
if (m_query_cache_queue.size() > m_query_cache_max){
718         java.lang.Object JavaDoc _old = m_query_cache_queue.firstElement();
719         m_query_cache_queue.removeElementAt(0);
720         m_query_cache_lookup.remove(_old);
721         }
722     }
723     return _id_known;
724     }
725
726     /**
727      * This method looks for a policy-value in the policies-hashtable.
728      *
729      * @param policies Hashtable to look in
730      * @param name The name of the policy
731      * @param defaultValue The default, if the hashtable does not contain a value
732      * @param maxValue The returned value does not exceed this value
733      *
734      * @exception PolicyTypeMismatch The type of the hastable-value does not have the expected type
735      * @exception InvalidPolicyValue The value is not the expected one
736      *
737      * @return A FollowOption not more than maxValue
738      */

739     protected FollowOption getPolicyValue(Hashtable policies,
740                       String JavaDoc name,
741                       FollowOption defaultValue,
742                       FollowOption maxValue)
743     throws PolicyTypeMismatch,
744     InvalidPolicyValue
745     {
746     FollowOption result = defaultValue;
747
748     Any value = (Any) policies.get(name);
749     if (value != null) {
750         try {
751         TypeCode _type = FollowOptionHelper.type();
752         if (! _type.equal(value.type()))
753             throw new PolicyTypeMismatch(new org.omg.CosTrading.Policy(name, value));
754         
755         result = FollowOptionHelper.extract(value);
756         }
757         catch (BAD_OPERATION e) {
758         throw new InvalidPolicyValue(new org.omg.CosTrading.Policy(name, value));
759         }
760     }
761     return FollowOption.from_int(Math.min(result.value(), maxValue.value()));
762     }
763
764     /**
765      * This method checks with LinkImpl, if anything has changed. If so,
766      * we update our local link-array. This is for efficiency since we don't have
767      * to retrieve the links always from LinkImpl, and because LinkImpl stores the
768      * Links in a Hashtable
769      *
770      */

771     private void updateLinks(){
772
773     if (m_link_if.linksChanged())
774         m_links_cache = m_link_if.getLinks();
775     }
776
777     /**
778      * This method sets up the QueryContainer-instances with the lookup-interfaces from
779      * the link-array. If the link_follow_rule does not exceed the limiting_follow_rule
780      * of a link the QueryContainer is handed to the QueryPropagato-object and executed.
781      *
782      * @param queries All new QueryContainer-objects are put here
783      * @param template Contains the queries parameters. Mainly for keeping the interface small.
784      * @param link_follow_rule The actual link_follow_rule-policy
785      * @param used_links For storing and lookup of links that have aready been accessed
786      */

787     private void distributeQuery(Vector queries,
788                  QueryContainer template,
789                  FollowOption link_follow_rule,
790                  Hashtable used_links){
791
792     updateLinks();
793     LinkInfo[] _links = m_links_cache;
794     for(int i = 0; i < _links.length; i++){
795         if (_links[i].limiting_follow_rule.value() >= link_follow_rule.value() &&
796         ! used_links.containsKey(_links[i].target)){
797         QueryContainer _query = new QueryContainer(template, _links[i].target);
798         queries.addElement(_query);
799         m_query_distrib.putWork(_query);
800         used_links.put(_links[i].target, _links[i].target);
801         }
802     }
803     }
804
805     protected int getPolicyValue(Hashtable policies,
806                  String JavaDoc name,
807                  int defaultValue,
808                  int maxValue)
809     throws PolicyTypeMismatch,
810     InvalidPolicyValue
811     {
812
813     int result = defaultValue;
814     Any value = (Any)policies.get(name);
815
816     if (value != null)
817     {
818         try
819         {
820         if (value.type().kind() != TCKind.tk_ulong)
821             throw new PolicyTypeMismatch(new org.omg.CosTrading.Policy(name, value));
822
823         result = value.extract_ulong();
824         }
825         catch (BAD_OPERATION e)
826         {
827         throw new InvalidPolicyValue(new org.omg.CosTrading.Policy(name, value));
828         }
829     }
830
831     result = Math.min(result, maxValue);
832     return result;
833
834     }
835
836
837     protected boolean getPolicyValue(Hashtable policies,
838                      String JavaDoc name,
839                      boolean defaultValue)
840     throws PolicyTypeMismatch,
841     InvalidPolicyValue
842     {
843
844     boolean result = defaultValue;
845     Any value = (Any)policies.get(name);
846
847     if (value != null)
848     {
849         try
850         {
851         if (value.type().kind() != TCKind.tk_boolean)
852             throw new PolicyTypeMismatch(new org.omg.CosTrading.Policy(name, value));
853
854         result = value.extract_boolean();
855         }
856         catch (BAD_OPERATION e)
857         {
858         throw new InvalidPolicyValue(new org.omg.CosTrading.Policy(name, value));
859         }
860     }
861     return result;
862     }
863
864
865     protected String JavaDoc getPolicyValue(Hashtable policies,
866                     String JavaDoc name,
867                     String JavaDoc defaultValue)
868     throws PolicyTypeMismatch,
869     InvalidPolicyValue
870     {
871    
872     String JavaDoc result = defaultValue;
873     Any value = (Any)policies.get(name);
874
875     if (value != null) {
876         try {
877         if (value.type().kind() != TCKind.tk_string)
878             throw new PolicyTypeMismatch(new org.omg.CosTrading.Policy(name, value));
879
880         result = value.extract_string();
881         }
882         catch (BAD_OPERATION e)
883         {
884         throw new InvalidPolicyValue(new org.omg.CosTrading.Policy(name, value));
885         }
886     }
887     return result;
888     }
889
890
891     protected void findCompatibleTypes(String JavaDoc type, Vector types)
892     {
893     // obtain the list of all service type names
894
SpecifiedServiceTypes whichTypes = new SpecifiedServiceTypes();
895     //whichTypes._default(ListOption.all);
896
// GB: whichTypes.all_dummy((short)0);
897
whichTypes.__default();
898
899     String JavaDoc[] allNames = m_repos.list_types(whichTypes);
900
901     // iterate through all service types, obtaining the full description
902
// of each to see if the service type in question is a supertype
903
for (int i = 0; i < allNames.length; i++) {
904         try {
905         TypeStruct ts = m_repos.fully_describe_type(allNames[i]);
906
907         for (int n = 0; n < ts.super_types.length; n++) {
908             if (type.equals(ts.super_types[n])) {
909             if (! types.contains(allNames[i]))
910                 types.addElement(allNames[i]);
911             break;
912             }
913         }
914         }
915         catch (IllegalServiceType e) {
916         // ignore
917
}
918         catch (UnknownServiceType e) {
919         // ignore
920
}
921     }
922     }
923
924
925     protected boolean considerOffer(
926                     SourceAdapter source,
927                     boolean useDynamic,
928                     boolean useModifiable,
929                     TypeStruct ts)
930     {
931     if (! useDynamic) {
932         Property[] props = source.getProperties();
933
934         // check if any property in the offer is dynamic
935
if (PropUtil.hasDynamicProperties(props))
936         return false;
937     }
938
939     if (! useModifiable) {
940         // check if any property in the offer is modifiable
941
for (int i = 0; i < ts.props.length; i++) {
942         // if the mode of the property is modifiable, then check
943
// if this offer has a definition for the property
944
if (ts.props[i].mode == PropertyMode.PROP_NORMAL ||
945             ts.props[i].mode == PropertyMode.PROP_MANDATORY)
946             if (source.exists(ts.props[i].name))
947             return false;
948         }
949     }
950
951     return true;
952     }
953 }
954
955
956
957
958
959
Popular Tags