Class: String

Inherits:
Object
  • Object
show all
Defined in:
lib/fisheye-crucible/type_converter.rb

Overview

By adding this method to String, the #to_ruby method can be called directly on the return data from RestClient. This, effectively, accomplishes turning a String of XML into the Ruby data types that make sense for the return types that Atlassian defined.

Instance Method Summary collapse

Instance Method Details

#boolean_to_true_false(xml_doc) ⇒ Boolean (private)

Converts a REXML::Document with element <boolean> into a true or false value.



107
108
109
# File 'lib/fisheye-crucible/type_converter.rb', line 107

def boolean_to_true_false(xml_doc)
  string_to_true_false(xml_doc.root.elements[1].text)
end

#changeset_to_hash(xml_doc) ⇒ Hash (private)

Takes Fisheye/Crucible's <changeset> return type and turns it in to a Hash.



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/fisheye-crucible/type_converter.rb', line 193

def changeset_to_hash(xml_doc)
  details = {}

  xml_doc.root.elements['//changeset'].attributes.each do |attribute|
    # Convert the value to an Int if the string is just a number
    int_attribute = attribute[1]
    if int_attribute =~ /^\d+$/
      details[attribute.first.to_sym] = int_attribute.to_i
    else
      details[attribute.first.to_sym] = int_attribute
    end
  end
  details[:log] = xml_doc.root.elements['//log'].text

  # Revisions is an Array of Hashes, where each Hash is a key/value pair that
  #   contains the path and revsion of one of the files/directories that's
  #   part of the changeset.
  details[:revisions] = []
  details[:revisions] << revisionkeys_to_array(xml_doc)

  details
end

#changesets_to_hash(xml_doc) ⇒ Hash (private)

Takes Fisheye/Crucible's <changesets> return type and turns it in to a Hash.



240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/fisheye-crucible/type_converter.rb', line 240

def changesets_to_hash(xml_doc)
  changesets = {}
  changesets[:csids] = []

  changesets[:max_return] = xml_doc.root.elements['//changesets'].
    attributes['maxReturn']

  xml_doc.root.elements['//csids'].each_element do |element|
    changesets[:csids] << element.text.to_i
  end

  changesets
end

#custom_to_array(xml_doc) ⇒ Array (private)

Takes Fisheye/Crucible's custom <row> return type (from a query) and turns it in to an Array of Hashes containing the results from the query.



259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
# File 'lib/fisheye-crucible/type_converter.rb', line 259

def custom_to_array(xml_doc)
  responses = []

  xml_doc.elements.each('//row') do |element|
    response = {}
    element.each do |subs|
      if subs.is_a? REXML::Text
      else
        # TODO: If subs.text is a Boolean string, it doesn't get converted
        # to the actual Boolean.  Same if it's an int or empty string.
        response[subs.name.to_sym] = subs.text
      end
    end
    responses << response
  end

  responses
end

#history_to_array(xml_doc) ⇒ Array<Hash> (private)

Takes Fisheye/Crucible's <history> return type and turns it in to an Array of revisions, which are Hashes.



176
177
178
179
180
181
182
183
184
185
186
# File 'lib/fisheye-crucible/type_converter.rb', line 176

def history_to_array(xml_doc)
  revisions = []

  revisions_xml = REXML::XPath.match(xml_doc, "//revisions/revision")
  revisions_xml.each do |revision_xml|
    revision = REXML::Document.new(revision_xml.to_s)
    revisions << revision_to_hash(revision)
  end

  revisions
end

#pathinfo_to_hash(xml_doc) ⇒ Hash<Hash> (private)

Takes Fisheye/Crucible's <pathinfo> return type and turns it in to a Hash of Hashes.



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/fisheye-crucible/type_converter.rb', line 133

def pathinfo_to_hash(xml_doc)
  path_names = {}

  xml_doc.root.each_element do |element|
    path_name = element.attributes["name"]
    path_names[path_name] = {}

    element.attributes.each_attribute do |attribute|
      next attribute if attribute.name.eql? 'name'
      boolean_value = string_to_true_false(attribute.value)
      path_names[path_name][attribute.name.to_sym] = boolean_value
    end
  end

  path_names
end

#revision_to_hash(xml_doc) ⇒ Hash (private)

Takes Fisheye/Crucible's <revision> return type and turns it in to a single Hash.



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/fisheye-crucible/type_converter.rb', line 155

def revision_to_hash(xml_doc)
  details = {}

  xml_doc.root.elements['//revision'].attributes.each do |attribute|
    # Convert the value to an Int if the string is just a number
    if attribute[1] =~ /^\d+$/
      details[attribute.first.to_sym] = attribute[1].to_i
    else
      details[attribute.first.to_sym] = attribute[1]
    end
  end
  details[:log] = xml_doc.root.elements['//log'].text

  details
end

#revisionkeys_to_array(xml_doc) ⇒ Array<Hash> (private)

Takes Fisheye/Crucible's <revisionkey> return type and turns it in to an Array of Hashes.



221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/fisheye-crucible/type_converter.rb', line 221

def revisionkeys_to_array(xml_doc)
  revisionkeys = []

  xml_doc.root.elements.each('//revisionkey') do |element|
    revisionkey = { :path => element.attributes['path'],
      :rev => element.attributes['rev'].to_i
    }

    revisionkeys << revisionkey
  end

  revisionkeys
end

#string_to_array(xml_doc) ⇒ Array (private)

Converts a REXML::Document with multiple elements of type <string> into an Array.



116
117
118
119
120
121
122
123
124
# File 'lib/fisheye-crucible/type_converter.rb', line 116

def string_to_array(xml_doc)
  responses = []
  xml_doc.root.each_element do |element|
    response_type = element.name
    responses << element.text
  end

  responses
end

#string_to_string(xml_doc) ⇒ String (private)

Converts a REXML::Document with 1 element of type <string> into a String.



86
87
88
# File 'lib/fisheye-crucible/type_converter.rb', line 86

def string_to_string(xml_doc)
  xml_doc.root.elements[1].text
end

#string_to_true_false(string) ⇒ Boolean, String (private)

Converts a String to its related Boolean type. If the string doesn't contain such a type, nil is returned.



95
96
97
98
99
100
# File 'lib/fisheye-crucible/type_converter.rb', line 95

def string_to_true_false(string)
  return true if string.eql? 'true'
  return false if string.eql? 'false'

  string
end

#to_rubyObject

Takes a String of XML then converts in to a correlating Ruby data type. Aside from the documentation for each private method below, here is the conversion table:

| Fisheye/Crucible Type  | Ruby Type               |
| string                 | String                  |
| boolean                | TrueClass, FalseClass   |
| pathinfo               | Hash with child Hashes  |
| revision               | Hash                    |
| history                | Array of revisions      |
| changeset              | Hash                    |
| changesets             | Hash of changesets      |
| revisionkey            | Array with child Hashes |
| row                    | Array                   |


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
# File 'lib/fisheye-crucible/type_converter.rb', line 23

def to_ruby
  doc = REXML::Document.new self

  type = doc.root.name
  doc_text = doc.root.text

  responses = []
  response_type = ''

  if type == 'error'
    return FisheyeCrucible::Error.new(doc_text)
  elsif type == 'response'
    doc.root.each_element do |element|
      # The data type
      response_type = element.name

      # Text for the next element
      responses << element.text
    end
  else
    message = "Not sure what to do with this response:\n#{doc_text}"
    return FisheyeCrucible::Error.new(message)
  end

  # If we have 0 or 1 actual strings, return the string or ""
  if response_type.eql? 'string' and responses.length <= 1
    return string_to_string(doc)
  # If we have mulitple strings, return the Array of Strings
  elsif response_type.eql? 'string'
    return string_to_array(doc)
  elsif response_type.eql? 'boolean'
    return boolean_to_true_false(doc)
  elsif response_type.eql? 'pathinfo'
    return pathinfo_to_hash(doc)
  elsif response_type.eql? 'revision'
    return revision_to_hash(doc)
  elsif response_type.eql? 'history'
    return history_to_array(doc)
  elsif response_type.eql? 'changeset'
    return changeset_to_hash(doc)
  elsif response_type.eql? 'changesets'
    return changesets_to_hash(doc)
  elsif response_type.eql? 'revisionkey'
    return revisionkeys_to_array(doc)
  elsif response_type.eql? 'row'
    return custom_to_array(doc)
  elsif response_type.eql? ''
    return ''
  end

  message = "Response type unknown: '#{response_type}'"

  FisheyeCrucible::Error.new(message)
end