1 2 5 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 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 private LinkImpl m_link_if; private static int m_query_counter; private Hashtable m_query_cache_lookup; private Vector m_query_cache_queue; private int m_query_cache_max = 100; private QueryPropagator m_query_distrib; private LinkInfo[] m_links_cache; 58 private static int count = 0; 59 private Logger logger; 60 61 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 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 m_link_if = link; 85 86 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 (ce.getMessage()); 101 } 102 } 103 104 105 111 public String _object_name() 112 { 113 return "TradingService"; 114 } 115 116 117 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 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 type_repos() 170 { 171 return m_support.getTypeRepos(); 172 } 173 174 175 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 247 public void query(String type, 248 String constr, 249 String 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 TypeStruct ts = m_repos.fully_describe_type(type); 272 273 Hashtable policyTable = new Hashtable(); 275 for (int i = 0; i < policies.length; i++) 276 { 277 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 String _id = getPolicyValue(policyTable, "request_id", new String ()); 286 Vector _generated_policies = new Vector(); 287 288 if (_id.length() == 0) 289 { 290 StringBuffer _new_id = new StringBuffer (new String (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 if (queryAlreadyEncountered(_id)) 305 { 306 offers.value = new Offer[0]; 308 limits_applied.value = new String [0]; 309 return; 310 } 311 312 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 (_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 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 boolean useDynamic; 353 if (supports_dynamic_properties() == false) 354 useDynamic = false; 355 else 356 useDynamic = 357 getPolicyValue(policyTable, "use_dynamic_properties", true); 358 359 boolean useModifiable; 362 if (supports_modifiable_properties() == false) 363 useModifiable = false; 364 else 365 useModifiable = 366 getPolicyValue(policyTable, "use_modifiable_properties", true); 367 368 boolean useProxyOffers; 371 if (supports_proxy_offers() == false) 372 useProxyOffers = false; 373 else 374 useProxyOffers = getPolicyValue(policyTable, "use_proxy_offers", true); 375 376 FollowOption link_follow_rule = getPolicyValue(policyTable, "link_follow_rule", 379 def_follow_policy(), 380 max_follow_policy()); 381 int hop_count = getPolicyValue(policyTable, "hop_count", def_hop_count(), max_hop_count()); 383 384 Any _hop = (Any) policyTable.get("hop_count"); 386 _hop.insert_ulong(_hop.extract_ulong() - 1); 387 388 389 QueryContainer _templ = new QueryContainer(type,constr, pref, 393 policies, desired_props, 394 how_many, null); 395 Vector _queries = new Vector(); 396 397 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 408 if (pref == null || pref.trim().length() == 0) 410 pref = "first"; 411 412 SchemaAdapter schema = new SchemaAdapter(ts); 414 415 Constraint constraint = new Constraint(schema); 416 Preference preference = new Preference(schema); 417 418 try { 419 constraint.parse(constr); 421 } 422 catch (ParseException ex) { 423 System.out.println("Illegal constraint '" + constr + "'"); 425 System.out.println(ex.getMessage()); 426 throw new IllegalConstraint(constr); 427 } 428 429 try { 430 preference.parse(pref); 432 } 433 catch (ParseException ex) { 434 System.out.println("Illegal preference '" + pref + "'"); 436 System.out.println(ex.getMessage()); 437 throw new IllegalPreference(pref); 438 } 439 440 441 Vector types = new Vector(); 444 types.addElement(type); 445 446 if (! exactType) 450 findCompatibleTypes(type, types); 451 452 try { 453 m_db.begin(OfferDatabase.READ); 454 455 int searchCount = 0; 459 Vector potentialOffers = new Vector(); 460 Enumeration e = types.elements(); 461 462 while (e.hasMoreElements() && searchCount < searchCard) 463 { 464 String typeName = (String )e.nextElement(); 465 Hashtable table = m_db.getOffers(typeName); 466 if (table == null) 467 continue; 468 469 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 if (useProxyOffers) { 489 e = types.elements(); 490 while (e.hasMoreElements() && searchCount < searchCard) 491 { 492 String typeName = (String )e.nextElement(); 493 Hashtable table = m_db.getProxyOffers(typeName); 494 if (table == null) 495 continue; 496 497 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 OfferEvaluator eval = new OfferEvaluator(type, constraint, pref, 515 policies, desired_props, potentialOffers, matchCard); 516 517 Vector matchingOffers = eval.getResults(); 523 524 525 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 Enumeration _results = _queries.elements(); 534 Vector _dropped = new Vector(); 535 536 Vector _applied_policies = new Vector(); 538 539 while (_results.hasMoreElements()){ 540 QueryContainer _distrib_query = (QueryContainer) _results.nextElement(); 541 try{ 542 _distrib_query.resultReady(); }catch(Exception _e){ 544 _e.printStackTrace(); 545 continue; } 547 548 UserException _query_exception = _distrib_query.getException(); 549 if (_query_exception != null){ 550 _dropped.addElement(_distrib_query); 551 continue; } 554 555 OfferSeqHolder _offers = _distrib_query.getOffers(); 557 if (_offers.value == null || _offers.value.length == 0){ 558 _dropped.addElement(_distrib_query); 560 continue; 561 } 562 563 for (int i = 0; i < _offers.value.length; i++) 567 matchingOffers.addElement(_offers.value[i]); 568 569 PolicyNameSeqHolder _policy_holder = _distrib_query.getLimits(); 571 if (_policy_holder.value != null){ 572 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 582 int matchCount = matchingOffers.size(); 583 584 Vector orderedOffers = preference.order(matchingOffers); 586 587 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 _element = e.nextElement(); 596 if (_element instanceof Offer){ 597 offers.value[count] = (Offer) _element; 598 } 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 if (seqCount < returnCount) { 611 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 _element = e.nextElement(); 618 if (_element instanceof Offer){ 619 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 _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 }catch(Exception _e){ 646 } 648 if (_offers == null){ 649 OfferIterator _itr = _itr_holder.value; 652 OfferSeqHolder _seq = new OfferSeqHolder(); 653 _itr.next_n(restCount - pos, _seq); _offers = _seq.value; 656 } 657 658 int _i = 0; 660 while (_i < _offers.length && pos < restCount){ 661 pos++; 662 rest.addElement(_offers[_i++]); 663 } 664 } 665 } 666 667 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 OfferIteratorImpl iter = new OfferIteratorImpl(_offer_array, 0); 676 iter._this_object( _orb() ); 677 offer_itr.value = iter._this(); 678 679 } 680 681 Enumeration _applied_limits = _applied_policies.elements(); 683 limits_applied.value = new String [_applied_policies.size()]; 684 int _i = 0; 685 while (_applied_limits.hasMoreElements()) 686 limits_applied.value[_i++] = (String ) _applied_limits.nextElement(); 687 688 } 689 finally { 690 m_db.end(); 691 } 692 693 } 694 695 696 708 private boolean queryAlreadyEncountered (String id){ 709 710 boolean _id_known = m_query_cache_lookup.containsKey(id); 711 if (! _id_known){ 712 m_query_cache_lookup.put(id, id); 714 m_query_cache_queue.addElement(id); 715 716 if (m_query_cache_queue.size() > m_query_cache_max){ 718 java.lang.Object _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 739 protected FollowOption getPolicyValue(Hashtable policies, 740 String 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 771 private void updateLinks(){ 772 773 if (m_link_if.linksChanged()) 774 m_links_cache = m_link_if.getLinks(); 775 } 776 777 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 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 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 getPolicyValue(Hashtable policies, 866 String name, 867 String defaultValue) 868 throws PolicyTypeMismatch, 869 InvalidPolicyValue 870 { 871 872 String 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 type, Vector types) 892 { 893 SpecifiedServiceTypes whichTypes = new SpecifiedServiceTypes(); 895 whichTypes.__default(); 898 899 String [] allNames = m_repos.list_types(whichTypes); 900 901 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 } 918 catch (UnknownServiceType e) { 919 } 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 if (PropUtil.hasDynamicProperties(props)) 936 return false; 937 } 938 939 if (! useModifiable) { 940 for (int i = 0; i < ts.props.length; i++) { 942 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 |