Class: XriResolver::SEPSelector
- Inherits:
-
Object
- Object
- XriResolver::SEPSelector
- Defined in:
- lib/xri_resolver.rb
Constant Summary collapse
- @@sel_categories =
usage: SEPList = XriResolver::SEPSelector.select(xrds, xrd, inputs)
where xrds is a valid XriResolver::AuthorityResolver object where inputs is a valid XriResolver::ParseInputParameters object
Returns an SEPList object corresponding to the selected SEPs, ordered by priority
(literally implements pseudocode in XRI Resolution 2.0 WD11 ED03 Section 10.6)
['Path', 'Type', 'MediaType'].freeze
- @@match_types =
['Positive', 'Default', 'Matched'].freeze
Class Method Summary collapse
Class Method Details
.select(xrds, xrd, inputs) ⇒ Object
723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 |
# File 'lib/xri_resolver.rb', line 723 def SEPSelector.select(xrds, xrd, inputs) ## initialize arrays selected_set = SEPList.new(xrds, xrd) default_set = SEPList.new(xrds, xrd) ## initialize nodefault to false nodefault = Hash.new @@sel_categories.each do |sel_category| nodefault[sel_category] = false end ## set nodefault according to subparameters nodefault['Path'] = inputs.nodefault_p nodefault['Type'] = inputs.nodefault_t nodefault['MediaType'] = inputs.nodefault_m ## normalize path path = (xrds.xri.path[0] == ?/) ? xrds.xri.path[1..-1] : xrds.xri.path ## remove leading '/' path = nil if path.empty? ## per XRI Resolution WD11 ED03 Section 6.1.1 ## set content values content = Hash.new content['Path'] = path content['Type'] = inputs.service_type content['MediaType'] = inputs.service_media_type ## "FOR EACH SEP" REXML::XPath.match(xrd, "*[local-name()='Service']", XRDNS).each do |sep| ## "CREATE set of SEL match flags" ## "SET all flags to FALSE" flag = Hash.new @@match_types.each do |match_type| flag[match_type] = Hash.new @@sel_categories.each do |sel_category| flag[match_type][sel_category] = false end end ## we now have ## flag = {"Default"=>{"MediaType"=>false, "Type"=>false, "Path"=>false}, ## "Positive"=>{"MediaType"=>false, "Type"=>false, "Path"=>false}, ## "Matched"=>{"MediaType"=>false, "Type"=>false, "Path"=>false}} ## "FOR EACH SEL of category x (where x=Type, Path or Mediatype)" REXML::XPath.match(sep, "*[(local-name()='Type')|(local-name()='Path')|(local-name()='MediaType')]", XRDNS).each do |sel| ## record match result on this sel this_sel_positive_match = false this_sel_default_match = false ## "SET Matched.x=TRUE" flag['Matched'][sel.name] = true ## XRI Resolution WD11 ED07 Section 13.3.4 unless sel.text or sel.attributes['match'] sel.attributes << REXML::Attribute.new('match', 'null') end ## determine match if sel.attributes['match'] and sel.attributes['match'] != 'content' ## determine match per XRI Resolution WD11 ED03 Section 10.3.2 case sel.attributes['match'] when 'any' this_sel_positive_match = true when 'default' this_sel_default_match = true when 'non-null' if content[sel.name] this_sel_positive_match = true end when 'null' unless content[sel.name] this_sel_positive_match = true end end else ## if no match attribute, see if there's a content match per 10.3.6, 10.3.7 and 10.3.8 ## TODO: implement normalization and other rules per these three sections if sel.text and content[sel.name] if sel.text.downcase == content[sel.name].downcase this_sel_positive_match = true end end end ## "IF match on this SEL is POSITIVE" if this_sel_positive_match if sel.attributes['select'] == 'true' ## sec 10.4.2 selected_set << [sep] break else flag['Positive'][sel.name] = true next end elsif this_sel_default_match ## if we have already found a positive SEL with the same name - sec. 10.3.5 if flag['Positive'][sel.name] next elsif nodefault[sel.name] next else flag['Default'][sel.name] = true next end else next end ## "End FOR EACH SEL" end ## "IF Matched.x=FALSE" (Sec 10.3.3) flag['Matched'].each do |selname, value| unless value ## this SEL hasn't been matched, i.e. was missing flag['Default'][selname] = true unless nodefault[selname] end end ## "IF Positive.Type=TRUE AND [...]" if flag['Positive']['Type'] and flag['Positive']['Path'] and flag['Positive']['MediaType'] selected_set << [sep] next end if (flag['Positive']['Type'] or flag['Default']['Type']) and (flag['Positive']['Path'] or flag['Default']['Path']) and (flag['Positive']['MediaType'] or flag['Default']['MediaType']) default_set << [sep, flag.dup] end ## "END FOR EACH SEP" end ## "IF SELECTED SET != EMPTY unless selected_set.empty? return selected_set end ## "IF DEFAULT SET != EMPTY ;see 10.5.2" unless default_set.empty? default_set.each do |sep, flag| ## two positive flags if (flag['Positive']['Type'] and flag['Positive']['Path']) or (flag['Positive']['Type'] and flag['Positive']['MediaType']) or (flag['Positive']['Path'] and flag['Positive']['MediaType']) selected_set << [sep] end end ## "IF SELECTED SET != EMPTY unless selected_set.empty? return selected_set end ## "FOR EACH SEP IN DEFAULT SET" default_set.each do |sep, flag| ## one positive flag if flag['Positive']['Type'] or flag['Positive']['Path'] or flag['Positive']['MediaType'] selected_set << [sep] end end end ## "IF SELECTED SET != EMPTY unless selected_set.empty? ## there was one positive flag in the default set return selected_set else ## all default flags return default_set end ## "RETURN EMPTY SET" return [] end |