class CF::UAA::ScimFilter
Public Class Methods
new(filter_string)
click to toggle source
# File lib/uaa/stub/scim.rb, line 474 def initialize(filter_string) if filter_string.nil? @filter = true else @input = StringScanner.new(filter_string) @filter = eat_phrase raise BadFilter unless @input.eos? end self rescue BadFilter => b raise BadFilter, "invalid filter expression at offset #{@input.pos}: #{@input.string}" end
Public Instance Methods
match?(entry)
click to toggle source
# File lib/uaa/stub/scim.rb, line 487 def match?(entry) @filter == true || eval(entry, @filter) end
Private Instance Methods
eat_expr()
click to toggle source
# File lib/uaa/stub/scim.rb, line 400 def eat_expr if @input.skip(/\s*\(\s*/) phrase = eat_phrase raise BadFilter unless @input.skip(/\s*\)\s*/) return phrase end raise BadFilter unless (attr = eat_word) && (op = eat_word("eq", "co", "sw", "pr", "gt", "ge", "lt", "le")) && (op == "pr" || value = eat_json_string) (attr_sym = StubScim.searchable_attribute(attr)) ? [:item, attr_sym, op, value] : [:undefined, attr, op, value] end
eat_json_string()
click to toggle source
# File lib/uaa/stub/scim.rb, line 375 def eat_json_string raise BadFilter unless @input.skip(/\s*"/) str = "" while true case when @input.scan(/[^\\"]+/); str << @input.matched when @input.scan(%r{\\["\\/]}); str << @input.matched[-1] when @input.scan(/\\[bfnrt]/); str << eval(%Q{"#{@input.matched}"}) when @input.scan(/\\u[0-9a-fA-F]{4}/); str << [Integer("0x#{@input.matched[2..-1]}")].pack("U") else break end end raise BadFilter unless @input.skip(/"\s*/) str end
eat_phrase()
click to toggle source
OR level
# File lib/uaa/stub/scim.rb, line 421 def eat_phrase phrase = [:or, eat_subphrase] while eat_word("or"); phrase << eat_subphrase end phrase.length == 2 ? phrase[1] : phrase end
eat_subphrase()
click to toggle source
AND level
# File lib/uaa/stub/scim.rb, line 414 def eat_subphrase phrase = [:and, eat_expr] while eat_word("and"); phrase << eat_expr end phrase.length == 2 ? phrase[1] : phrase end
eat_word(*words)
click to toggle source
# File lib/uaa/stub/scim.rb, line 391 def eat_word(*words) @input.skip(/\s*/) return unless s = @input.scan(/(\S+)\s*/) w = @input[1].downcase return w if words.empty? || words.include?(w) @input.unscan false end
eval(entry, filtr)
click to toggle source
# File lib/uaa/stub/scim.rb, line 452 def eval(entry, filtr) undefd = 0 case filtr[0] when :undefined ; nil when :item ; eval_expr(entry, filtr[1], filtr[2], filtr[3]) when :or filtr[1..-1].each { |f| return true if (res = eval(entry, f)) == true undefd += 1 if res.nil? } filtr.length == undefd + 1 ? nil: false when :and filtr[1..-1].each { |f| return false if (res = eval(entry, f)) == false undefd += 1 if res.nil? } filtr.length == undefd + 1 ? nil: true end end
eval_expr(entry, attr, op, value)
click to toggle source
# File lib/uaa/stub/scim.rb, line 427 def eval_expr(entry, attr, op, value) return false unless val = entry[attr] return true if op == "pr" case attr when *StubScim::REFERENCES return nil unless op == "eq" val.each {|v| return true if v.casecmp(value) == 0 } false when *StubScim::GENERAL_MULTI return nil unless op == "eq" val.each {|k, v| return true if v.casecmp(value) == 0 } false else case op when "eq"; val.casecmp(value) == 0 when "sw"; val =~ /^#{Regexp.escape(value)}/i when "co"; val =~ /#{Regexp.escape(value)}/i when "gt"; val.casecmp(value) > 0 when "ge"; val.casecmp(value) >= 0 when "lt"; val.casecmp(value) < 0 when "le"; val.casecmp(value) <= 0 end end end