Class: XriParser::AuthorityParser

Inherits:
Object
  • Object
show all
Defined in:
lib/xri_parser.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(xri, get_root = true) ⇒ AuthorityParser

Returns a new instance of AuthorityParser.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/xri_parser.rb', line 14

def initialize(xri, get_root=true)
  @root = String.new
  @subsegments = Array.new
  xri = xri.strip rescue nil
  xri = xri_strip_scheme(xri) rescue nil
  raise 'No XRI Received' if xri.nil? or xri.empty?
  #get root
  if get_root
    gcs_chars = Regexp.escape("@=!+*()")
    gcs_connectors = Regexp.escape("@=!+*")
    dns_rgx = Regexp.new("\\A(\\$dns\\*[^#{gcs_chars}]+)([#{gcs_connectors}].*)\\z", true)
    ## equivalent to:  /\A(\$dns\*[^@=!\+\*\(\)]+)([@=!\+\*].*)\z/i
    ip_rgx = Regexp.new("\\A(\\$ip\\*[^#{gcs_chars}]+)([#{gcs_connectors}].*)\\z", true)
    ## equivalent to:  /\A(\$ip\*[^@=!\+\*\(\)]+)([@=!\+\*].*)\z/i
    simple_roots = [?=, ?@, ?!, ?+]
    if simple_roots.include? xri[0]
      @root = xri[0].chr
      xri = xri[1..-1] # xri is now the rest of xri after the root
    elsif xri[0,2] == '$('
      paren = 0
      pointer = 0
      
      @root = '$'
      xri = xri[1..-1]
      xri.each_byte do |c|
        paren += 1 if c == ?(
        paren -= 1 if c == ?)
        pointer += 1
        @root << c.chr
        break if paren.zero?
      end

      xri = xri[pointer..-1] # xri is now the rest of xri after the root
    elsif xri =~ dns_rgx
      @root = $1
      xri = $2
    elsif xri =~ ip_rgx
      @root = $1
      xri = $2
    else
      raise XRIRootMissing, 'No XRI root'
    end
  end

  if xri.length < 1
    return true
  end
  if (@root == '!') and (xri[0] != ?!)
    raise 'XRIs in the ! registry must start with !'
  end
  
  subsegment_delimiters = [?@, ?=, ?!, ?+, ?*]
  #add implicit * after root if neccessary
  xri.insert(0,'*') unless subsegment_delimiters.include? xri[0] 
  open_paren = 0
  close_paren = 0
  segment_buf = String.new
  
  # get subsegments
  xri.each_byte do |c|
    open_paren += 1 if c == ?(
    close_paren += 1 if c == ?)
    # if we're inside an xref keep adding to buffer
    if (open_paren > 0) and (open_paren != close_paren)
      segment_buf << c.chr
      next
    end
    # starting a new subsegment
    if subsegment_delimiters.include? c
      # flush the buffer
      @subsegments << segment_buf unless segment_buf.empty?
      # initialize a new buffer
      segment_buf = ""
      # add the delimiter to the buffer
      segment_buf << c.chr
    elsif (c == ?/) or (c == ??) or (c == ?#) #end of authority parsing
      break
    else
      # add the character to the buffer
      segment_buf << c.chr
    end
  end

  @subsegments << segment_buf # flush buffer at the end
  @local = xri[@subsegments.to_s.length..-1] # the rest of xri
  @path = @local.index('?') ? @local[/^(.*?)\?/, 1] : @local # path is everything up to a question mark
  @query = @local.index('?') ? @local[/\?(.*)$/, 1] : '' # query is everything after a question mark
  @authority = self.normalized
  @appendable_query = make_appendable_query(@query)
  @qxri = "#{@authority}#{@path}"
  @qxri << "?#{@appendable_query}" unless  @appendable_query.empty?
  true
end

Instance Attribute Details

#appendable_queryObject (readonly)

Returns the value of attribute appendable_query.



11
12
13
# File 'lib/xri_parser.rb', line 11

def appendable_query
  @appendable_query
end

#authorityObject (readonly)

Returns the value of attribute authority.



11
12
13
# File 'lib/xri_parser.rb', line 11

def authority
  @authority
end

#localObject (readonly)

Returns the value of attribute local.



11
12
13
# File 'lib/xri_parser.rb', line 11

def local
  @local
end

#pathObject

Returns the value of attribute path.



12
13
14
# File 'lib/xri_parser.rb', line 12

def path
  @path
end

#queryObject (readonly)

Returns the value of attribute query.



11
12
13
# File 'lib/xri_parser.rb', line 11

def query
  @query
end

#qxriObject (readonly)

Returns the value of attribute qxri.



11
12
13
# File 'lib/xri_parser.rb', line 11

def qxri
  @qxri
end

#rootObject (readonly)

Returns the value of attribute root.



11
12
13
# File 'lib/xri_parser.rb', line 11

def root
  @root
end

#subsegmentsObject (readonly)

Returns the value of attribute subsegments.



11
12
13
# File 'lib/xri_parser.rb', line 11

def subsegments
  @subsegments
end

Class Method Details

.parse(xri, get_root = true) ⇒ Object



6
7
8
# File 'lib/xri_parser.rb', line 6

def parse(xri, get_root=true)
  AuthorityParser.new(xri, get_root)
end

Instance Method Details

#communityObject



123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/xri_parser.rb', line 123

def community
  all_but_last_seg = @subsegments[0..-2].to_s
  # strip off leading * if i-name and root is = or @
  if @root == '@' or @root == '='
    all_but_last_seg = all_but_last_seg[1..-1] if all_but_last_seg[0] == ?*
  end
  unless all_but_last_seg.nil? or all_but_last_seg.empty?
    @root + all_but_last_seg
  else
    @root
  end
end

#fully_qualifiedObject



150
151
152
# File 'lib/xri_parser.rb', line 150

def fully_qualified
  @root + @subsegments.to_s
end

#is_inumber?Boolean

Returns:

  • (Boolean)


118
119
120
121
# File 'lib/xri_parser.rb', line 118

def is_inumber?
  @subsegments.each {|seg| return false if seg[0] != ?!}
  true
end

#local_inameObject



136
137
138
139
140
141
142
143
144
# File 'lib/xri_parser.rb', line 136

def local_iname
  unless self.is_inumber?
    if @subsegments.last[0] == ?* # strip off leading * on local i-name
      @subsegments.last[1..-1]
    else
      @subsegments.last
    end
  end
end

#local_inumberObject



146
147
148
# File 'lib/xri_parser.rb', line 146

def local_inumber
  @subsegments.last[0..-1] if self.is_inumber?
end

#make_appendable_query(query) ⇒ Object



162
163
164
165
166
167
168
169
170
171
172
# File 'lib/xri_parser.rb', line 162

def make_appendable_query(query)
  q = Array.new
  #extract leading extra "?"s
  if query =~ /^([\?]+)(.*)$/ 
    q << $1 
    query = $2
  end
  ## remove XRI control params (and our barxdemo param)
  query.scan(/[^&]+/).each {|tok| q << tok unless tok =~ /^(barxdemo=|_xrd_r=|_xrd_t=|_xrd_m=)/}
  q.to_s
end

#normalizedObject



154
155
156
157
158
159
160
# File 'lib/xri_parser.rb', line 154

def normalized
  if @root == '@' or @root == '='
    @root + ((@subsegments.to_s[0,1] == '!') ? @subsegments.to_s : @subsegments.to_s[1..-1])
  else
    @root + @subsegments.to_s
  end
end

#to_hashObject



174
175
176
177
178
179
180
181
182
183
184
# File 'lib/xri_parser.rb', line 174

def to_hash
  h = Hash.new
  h[:authority] = @authority
  h[:local] = @local
  h[:path] = @path
  h[:query] = @query
  h[:qxri] = @qxri
  h[:root] = @root
  h[:subsegments] = @subsegments
  h
end

#to_xmlObject



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/xri_parser.rb', line 186

def to_xml
  xml = %Q{<?xml version="1.0" encoding="UTF-8"?>}
  xml << %Q{<parsed req="#{@qxri}">}
  xml << %Q{<root>#{@root}</root>}
  xml << %Q{<subsegments>}
  @subsegments.each {|sub| xml << %Q{<subsegment>#{sub}</subsegment>} } 
  xml << %Q{</subsegments>}
	xml << %Q{<authority>#{@authority}</authority>}
	xml << %Q{<local>#{@local}</local>}
	xml << %Q{<path>#{@path}</path>}
	xml << %Q{<query>#{@query}</query>}
	xml << %Q{<qxri>#{@qxri}</qxri>}
	xml << %Q{</parsed>}
	output = ""
	doc = REXML::Document.new(xml)
	doc.simple_write(output, 0)
	output
end

#xri_strip_scheme(xri) ⇒ Object



108
109
110
111
112
113
114
115
116
# File 'lib/xri_parser.rb', line 108

def xri_strip_scheme(xri)
  if xri[0..5] =~ /xri:\/\//i
    xri[6..-1]
  elsif xri[0..3] =~ /xri:/i
    xri[4..-1]
  else
    xri
  end
end