om 1.8.0 → 1.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +1 -0
  3. data/.rubocop.yml +1 -0
  4. data/.rubocop_todo.yml +382 -0
  5. data/.travis.yml +10 -0
  6. data/Rakefile +1 -1
  7. data/container_spec.rb +14 -14
  8. data/gemfiles/gemfile.rails3 +11 -0
  9. data/gemfiles/gemfile.rails4 +10 -0
  10. data/lib/om.rb +9 -12
  11. data/lib/om/samples/mods_article.rb +9 -9
  12. data/lib/om/tree_node.rb +6 -6
  13. data/lib/om/version.rb +1 -1
  14. data/lib/om/xml.rb +18 -20
  15. data/lib/om/xml/container.rb +12 -12
  16. data/lib/om/xml/document.rb +3 -7
  17. data/lib/om/xml/dynamic_node.rb +45 -50
  18. data/lib/om/xml/named_term_proxy.rb +13 -13
  19. data/lib/om/xml/node_generator.rb +3 -3
  20. data/lib/om/xml/template_registry.rb +18 -26
  21. data/lib/om/xml/term.rb +30 -46
  22. data/lib/om/xml/term_value_operators.rb +52 -56
  23. data/lib/om/xml/term_xpath_generator.rb +51 -57
  24. data/lib/om/xml/terminology.rb +8 -10
  25. data/lib/om/xml/validation.rb +19 -19
  26. data/lib/om/xml/vocabulary.rb +4 -4
  27. data/lib/tasks/om.rake +4 -6
  28. data/om.gemspec +1 -2
  29. data/spec/integration/differentiated_elements_spec.rb +2 -2
  30. data/spec/integration/element_value_spec.rb +13 -13
  31. data/spec/integration/proxies_and_ref_spec.rb +15 -15
  32. data/spec/integration/querying_documents_spec.rb +24 -18
  33. data/spec/integration/rights_metadata_integration_example_spec.rb +18 -18
  34. data/spec/integration/selective_querying_spec.rb +1 -1
  35. data/spec/integration/serialization_spec.rb +13 -13
  36. data/spec/integration/set_reentrant_terminology_spec.rb +7 -7
  37. data/spec/integration/xpathy_stuff_spec.rb +16 -16
  38. data/spec/spec_helper.rb +2 -3
  39. data/spec/unit/container_spec.rb +28 -29
  40. data/spec/unit/document_spec.rb +49 -50
  41. data/spec/unit/dynamic_node_spec.rb +55 -47
  42. data/spec/unit/named_term_proxy_spec.rb +16 -16
  43. data/spec/unit/node_generator_spec.rb +7 -7
  44. data/spec/unit/nokogiri_sanity_spec.rb +30 -30
  45. data/spec/unit/om_spec.rb +5 -5
  46. data/spec/unit/template_registry_spec.rb +69 -69
  47. data/spec/unit/term_builder_spec.rb +77 -77
  48. data/spec/unit/term_spec.rb +78 -72
  49. data/spec/unit/term_value_operators_spec.rb +186 -191
  50. data/spec/unit/term_xpath_generator_spec.rb +37 -43
  51. data/spec/unit/terminology_builder_spec.rb +85 -85
  52. data/spec/unit/terminology_spec.rb +98 -98
  53. data/spec/unit/validation_spec.rb +22 -22
  54. data/spec/unit/xml_serialization_spec.rb +21 -22
  55. data/spec/unit/xml_spec.rb +7 -7
  56. metadata +143 -147
@@ -1,9 +1,9 @@
1
1
  class OM::XML::NamedTermProxy
2
-
2
+
3
3
  attr_accessor :proxy_pointer, :name, :terminology
4
-
4
+
5
5
  include OM::TreeNode
6
-
6
+
7
7
  # Creates a Named Proxy that points to another term in the Terminology.
8
8
  # Unlike regular terms, NamedTermProxy requires you to provide a reference to the containing Terminology.
9
9
  # This is to ensure that it will always be able to look up the term that it's referencing.
@@ -14,13 +14,13 @@ class OM::XML::NamedTermProxy
14
14
  def initialize(name, proxy_pointer, terminology, opts={})
15
15
  opts = {:namespace_prefix=>"oxns", :ancestors=>[], :children=>{}}.merge(opts)
16
16
  [:children, :ancestors, :index_as].each do |accessor_name|
17
- instance_variable_set("@#{accessor_name}", opts.fetch(accessor_name, nil) )
17
+ instance_variable_set("@#{accessor_name}", opts.fetch(accessor_name, nil) )
18
18
  end
19
19
  @terminology = terminology
20
20
  @name = name
21
21
  @proxy_pointer = proxy_pointer
22
22
  end
23
-
23
+
24
24
  def proxied_term
25
25
  if self.parent.nil?
26
26
  pt = self.terminology.retrieve_term(*self.proxy_pointer)
@@ -33,18 +33,18 @@ class OM::XML::NamedTermProxy
33
33
  return pt
34
34
  end
35
35
  end
36
-
36
+
37
37
  # do nothing -- this is to prevent errors when the parent term calls generate_xpath_queries! on its children
38
38
  def generate_xpath_queries!
39
39
  # do nothing
40
40
  end
41
-
41
+
42
42
  # A proxy term can never serve as the root term of a Terminology.
43
43
  # Explicitly setting is_root_term? to return false to support proxies that are _at_ the root of the Terminology but aren't _the_ root term.
44
44
  def is_root_term?
45
- return false
45
+ false
46
46
  end
47
-
47
+
48
48
  ##
49
49
  # Always co-erce :index_as attributes into an Array
50
50
  def index_as
@@ -54,10 +54,10 @@ class OM::XML::NamedTermProxy
54
54
  self.proxied_term.index_as
55
55
  end
56
56
  end
57
-
57
+
58
58
  # Any unknown method calls will be proxied to the proxied term
59
- def method_missing method, *args, &block
60
- return self.proxied_term.send(method, *args)
59
+ def method_missing method, *args, &block
60
+ self.proxied_term.send(method, *args)
61
61
  end
62
-
62
+
63
63
  end
@@ -1,5 +1,5 @@
1
1
  module OM::XML::NodeGenerator
2
-
2
+
3
3
  # Module Methods -- These methods can be called directly on the Module itself
4
4
  # @param OM::XML::Term term The term to generate a node based on
5
5
  # @param String builder_new_value The new value to insert into the generated node
@@ -14,8 +14,8 @@ module OM::XML::NodeGenerator
14
14
  builder = Nokogiri::XML::Builder.new do |xml|
15
15
  eval( builder_call_body )
16
16
  end
17
-
18
- return builder.doc
17
+
18
+ builder.doc
19
19
  end
20
20
 
21
21
  end
@@ -1,10 +1,10 @@
1
- # Extend an OM::XML::Document with reusable templates, then use them to add content to
1
+ # Extend an OM::XML::Document with reusable templates, then use them to add content to
2
2
  # instance documents.
3
3
  #
4
4
  # Example:
5
5
  #
6
6
  # require 'om/samples/mods_article'
7
- #
7
+ #
8
8
  # class OM::Samples::ModsArticle
9
9
  # define_template :personalName do |xml, family, given, address|
10
10
  # xml.name(:type => 'personal') do
@@ -13,7 +13,7 @@
13
13
  # xml.namePart(:type => 'termsOfAddress') { xml.text(address) }
14
14
  # end
15
15
  # end
16
- #
16
+ #
17
17
  # define_template :role do |xml, text, attrs|
18
18
  # xml.role do
19
19
  # attrs = { :type => 'text' }.merge(attrs)
@@ -21,9 +21,9 @@
21
21
  # end
22
22
  # end
23
23
  # end
24
- #
24
+ #
25
25
  # mods = OM::Samples::ModsArticle.from_xml(File.read('./spec/fixtures/CBF_MODS/ARS0025_016.xml'))
26
- #
26
+ #
27
27
  # mods.add_previous_sibling_node([:person => 0], :personalName, 'Shmoe', 'Joseph', 'Dr.') { |person|
28
28
  # person.add_child(mods.template(:role, 'author', :authority => 'marcrelator'))
29
29
  # person.add_child(mods.template(:role, 'sub', :authority => 'local', :type => 'code'))
@@ -44,7 +44,7 @@ class OM::XML::TemplateRegistry
44
44
  unless node_type.is_a?(Symbol)
45
45
  raise TypeError, "Registered node type must be a Symbol (e.g., :person)"
46
46
  end
47
-
47
+
48
48
  @templates[node_type] = block
49
49
  node_type
50
50
  end
@@ -77,11 +77,9 @@ class OM::XML::TemplateRegistry
77
77
  result = create_detached_node(nil, node_type, *args)
78
78
  # Strip namespaces from text and CDATA nodes. Stupid Nokogiri.
79
79
  result.traverse { |node|
80
- if node.is_a?(Nokogiri::XML::CharacterData)
81
- node.namespace = nil
82
- end
80
+ node.namespace = nil if node.is_a?(Nokogiri::XML::CharacterData)
83
81
  }
84
- return result
82
+ result
85
83
  end
86
84
 
87
85
  # +instantiate+ a node and add it as a child of the [Nokogiri::XML::Node] specified by +target_node+
@@ -125,7 +123,7 @@ class OM::XML::TemplateRegistry
125
123
  def swap(target_node, node_type, *args, &block)
126
124
  attach_node(:swap, target_node, :parent, node_type, *args, &block)
127
125
  end
128
-
126
+
129
127
  def methods
130
128
  super + @templates.keys.collect { |k| k.to_s }
131
129
  end
@@ -140,7 +138,7 @@ class OM::XML::TemplateRegistry
140
138
  end
141
139
 
142
140
  private
143
-
141
+
144
142
  # Create a new Nokogiri::XML::Node based on the template for +node_type+
145
143
  #
146
144
  # @param [Nokogiri::XML::Node] builder_node The node to use as starting point for building the node using Nokogiri::XML::Builder.with(builder_node). This provides namespace info, etc for constructing the new Node object. If nil, defaults to {OM::XML::TemplateRegistry#empty_root_node}. This is just used to create the new node and will not be included in the response.
@@ -148,13 +146,9 @@ class OM::XML::TemplateRegistry
148
146
  # @param [Array] args any additional args
149
147
  def create_detached_node(builder_node, node_type, *args)
150
148
  proc = @templates[node_type]
151
- if proc.nil?
152
- raise NameError, "Unknown node type: #{node_type.to_s}"
153
- end
154
- if builder_node.nil?
155
- builder_node = empty_root_node
156
- end
157
-
149
+ raise NameError, "Unknown node type: #{node_type.to_s}" if proc.nil?
150
+ builder_node = empty_root_node if builder_node.nil?
151
+
158
152
  builder = Nokogiri::XML::Builder.with(builder_node) do |xml|
159
153
  proc.call(xml,*args)
160
154
  end
@@ -165,11 +159,11 @@ class OM::XML::TemplateRegistry
165
159
  #
166
160
  # @param [Symbol] method name that should be called on +target_node+, usually a Nokogiri::XML::Node instance method
167
161
  # @param [Nokogiri::XML::Node or Nokogiri::XML::NodeSet with only one Node in it] target_node
168
- # @param [Symbol] builder_node_offset Indicates node to use as the starting point for _constructing_ the new node using {OM::XML::TemplateRegistry#create_detached_node}. If this is set to :parent, target_node.parent will be used. Otherwise, target_node will be used.
162
+ # @param [Symbol] builder_node_offset Indicates node to use as the starting point for _constructing_ the new node using {OM::XML::TemplateRegistry#create_detached_node}. If this is set to :parent, target_node.parent will be used. Otherwise, target_node will be used.
169
163
  # @param node_type
170
164
  # @param [Array] args any additional arguments for creating the node
171
165
  def attach_node(method, target_node, builder_node_offset, node_type, *args, &block)
172
- if target_node.is_a?(Nokogiri::XML::NodeSet) and target_node.length == 1
166
+ if target_node.is_a?(Nokogiri::XML::NodeSet) && target_node.length == 1
173
167
  target_node = target_node.first
174
168
  end
175
169
  builder_node = builder_node_offset == :parent ? target_node.parent : target_node
@@ -177,9 +171,7 @@ class OM::XML::TemplateRegistry
177
171
  result = target_node.send(method, new_node)
178
172
  # Strip namespaces from text and CDATA nodes. Stupid Nokogiri.
179
173
  new_node.traverse { |node|
180
- if node.is_a?(Nokogiri::XML::CharacterData)
181
- node.namespace = nil
182
- end
174
+ node.namespace = nil if node.is_a?(Nokogiri::XML::CharacterData)
183
175
  }
184
176
  if block_given?
185
177
  yield result
@@ -187,9 +179,9 @@ class OM::XML::TemplateRegistry
187
179
  return result
188
180
  end
189
181
  end
190
-
182
+
191
183
  def empty_root_node
192
184
  Nokogiri::XML('<root/>').root
193
185
  end
194
-
186
+
195
187
  end
data/lib/om/xml/term.rb CHANGED
@@ -56,16 +56,14 @@ class OM::XML::Term
56
56
  trail = ""
57
57
  nodes_visited.each_with_index do |node, z|
58
58
  trail << node.name.inspect
59
- unless z == nodes_visited.length-1
60
- trail << " => "
61
- end
59
+ trail << " => " unless z == nodes_visited.length-1
62
60
  end
63
61
  raise OM::XML::Terminology::CircularReferenceError, "Circular reference in Terminology: #{trail}"
64
62
  end
65
63
  result << target
66
64
  result.concat( target.lookup_refs(nodes_visited << self) )
67
65
  end
68
- return result
66
+ result
69
67
  end
70
68
 
71
69
  # If a :ref value has been set, looks up the target of that ref and merges the target's settings & children with the current builder's settings & children
@@ -81,7 +79,7 @@ class OM::XML::Term
81
79
  @settings[:path] = name_of_last_ref.to_s
82
80
  end
83
81
  @settings.delete :ref
84
- return self
82
+ self
85
83
  end
86
84
 
87
85
  # Returns a new Hash that merges +downstream_hash+ with +upstream_hash+
@@ -96,7 +94,7 @@ class OM::XML::Term
96
94
  up.delete(setting_name)
97
95
  end
98
96
  end
99
- return up.merge(dn)
97
+ up.merge(dn)
100
98
  end
101
99
 
102
100
  # Builds a new OM::XML::Term based on the Builder object's current settings
@@ -121,31 +119,29 @@ class OM::XML::Term
121
119
  term.generate_xpath_queries!
122
120
  end
123
121
 
124
- return term
122
+ term
125
123
  end
126
124
 
127
125
  # :data_type accessor has been deprecated in favor of :type
128
126
  # Any value set for :data_type will get set for :type instead
129
127
  def data_type value
130
128
  @settings[:type] = value
131
- return self
129
+ self
132
130
  end
133
131
  deprecation_deprecate :data_type
134
132
 
135
133
  # We have to add this method so it will play nice with ruby 1.8.7
136
134
  def type value
137
135
  @settings[:type] = value
138
- return self
136
+ self
139
137
  end
140
138
 
141
139
 
142
140
  # Any unknown method calls will add an entry to the settings hash and return the current object
143
141
  def method_missing method, *args, &block
144
- if args.length == 1
145
- args = args.first
146
- end
142
+ args = args.first if args.length == 1
147
143
  @settings[method] = args
148
- return self
144
+ self
149
145
  end
150
146
  end
151
147
 
@@ -197,9 +193,9 @@ class OM::XML::Term
197
193
  # @param name [Symbol] the name to refer to this term by
198
194
  # @param opts [Hash]
199
195
  # @options opts [Array] :index_as a list of indexing hints provided to to_solr
200
- # @options opts [String] :path partial xpath that points to the node.
201
- # @options opts [Hash] :attributes xml attributes to match in the selector
202
- # @options opts [String] :namespace_prefix xml namespace for this node
196
+ # @options opts [String] :path partial xpath that points to the node.
197
+ # @options opts [Hash] :attributes xml attributes to match in the selector
198
+ # @options opts [String] :namespace_prefix xml namespace for this node
203
199
  # @options opts [Symbol] :type one of :string, :date, :integer. Defaults to :string
204
200
  def initialize(name, opts={}, terminology=nil)
205
201
  opts = {:ancestors=>[], :children=>{}}.merge(opts)
@@ -211,15 +207,11 @@ class OM::XML::Term
211
207
 
212
208
  unless terminology.nil?
213
209
  if opts[:namespace_prefix].nil?
214
- unless terminology.namespaces["xmlns"].nil?
215
- @namespace_prefix = "oxns"
216
- end
210
+ @namespace_prefix = "oxns" unless terminology.namespaces["xmlns"].nil?
217
211
  end
218
212
  end
219
213
  @name = name
220
- if @path.nil? || @path.empty?
221
- @path = name.to_s
222
- end
214
+ @path = name.to_s if @path.nil? || @path.empty?
223
215
  end
224
216
 
225
217
 
@@ -237,7 +229,7 @@ class OM::XML::Term
237
229
  end
238
230
  new_values
239
231
  end
240
-
232
+
241
233
  # @param val [String,Date,Integer]
242
234
  def serialize (val)
243
235
  case type
@@ -245,7 +237,7 @@ class OM::XML::Term
245
237
  val.to_s
246
238
  when :boolean
247
239
  val.to_s
248
- else
240
+ else
249
241
  val
250
242
  end
251
243
  end
@@ -255,14 +247,14 @@ class OM::XML::Term
255
247
  def deserialize(val)
256
248
  case type
257
249
  when :date
258
- #TODO use present?
250
+ # TODO use present?
259
251
  val.map { |v| !v.empty? ? Date.parse(v) : nil}
260
252
  when :integer
261
- #TODO use blank?
253
+ # TODO use blank?
262
254
  val.map { |v| v.empty? ? nil : v.to_i}
263
255
  when :boolean
264
256
  val.map { |v| v == 'true' }
265
- else
257
+ else
266
258
  val
267
259
  end
268
260
  end
@@ -287,7 +279,7 @@ class OM::XML::Term
287
279
  new_mapper.add_child(child)
288
280
  end
289
281
 
290
- return new_mapper
282
+ new_mapper
291
283
  end
292
284
 
293
285
  ##
@@ -312,7 +304,7 @@ class OM::XML::Term
312
304
  return nil
313
305
  end
314
306
  end
315
- return target
307
+ target
316
308
  end
317
309
 
318
310
  def is_root_term?
@@ -336,7 +328,7 @@ class OM::XML::Term
336
328
  else
337
329
  node_options = ["\':::builder_new_value:::\'"]
338
330
  end
339
- if !self.attributes.nil?
331
+ unless self.attributes.nil?
340
332
  self.attributes.merge(extra_attributes).each_pair do |k,v|
341
333
  node_options << "\'#{k}\'=>\'#{v}\'" unless v == :none
342
334
  end
@@ -346,7 +338,7 @@ class OM::XML::Term
346
338
  if builder_method.include?(":")
347
339
  builder_ref = "xml['#{self.path[0..path.index(":")-1]}']"
348
340
  builder_method = self.path[path.index(":")+1..-1]
349
- elsif !self.namespace_prefix.nil? and self.namespace_prefix != 'oxns'
341
+ elsif !self.namespace_prefix.nil? && self.namespace_prefix != 'oxns'
350
342
  builder_ref = "xml['#{self.namespace_prefix}']"
351
343
  elsif self.path.kind_of?(Hash) && self.path[:attribute]
352
344
  builder_method = "@#{self.path[:attribute]}"
@@ -355,7 +347,7 @@ class OM::XML::Term
355
347
  builder_method += "_"
356
348
  end
357
349
  template = "#{builder_ref}.#{builder_method}( #{OM::XML.delimited_list(node_options)} )" + node_child_template
358
- return template.gsub( /:::(.*?):::/ ) { '#{'+$1+'}' }
350
+ template.gsub( /:::(.*?):::/ ) { '#{'+$1+'}' }
359
351
  end
360
352
 
361
353
  # Generates absolute, relative, and constrained xpaths for the term, setting xpath, xpath_relative, and xpath_constrained accordingly.
@@ -365,7 +357,7 @@ class OM::XML::Term
365
357
  self.xpath_constrained = OM::XML::TermXpathGenerator.generate_constrained_xpath(self)
366
358
  self.xpath_relative = OM::XML::TermXpathGenerator.generate_relative_xpath(self)
367
359
  self.children.each_value {|child| child.generate_xpath_queries! }
368
- return self
360
+ self
369
361
  end
370
362
 
371
363
  # Return an XML representation of the Term
@@ -380,9 +372,7 @@ class OM::XML::Term
380
372
  def to_xml(options={}, document=Nokogiri::XML::Document.new)
381
373
  builder = Nokogiri::XML::Builder.with(document) do |xml|
382
374
  xml.term(:name=>name) {
383
- if is_root_term?
384
- xml.is_root_term("true")
385
- end
375
+ xml.is_root_term("true") if is_root_term?
386
376
  xml.path path
387
377
  xml.namespace_prefix namespace_prefix
388
378
  unless attributes.nil? || attributes.empty?
@@ -393,15 +383,11 @@ class OM::XML::Term
393
383
  }
394
384
  end
395
385
  xml.index_as {
396
- unless index_as.nil?
397
- index_as.each { |index_type| xml.index_type }
398
- end
386
+ index_as.each { |index_type| xml.index_type } unless index_as.nil?
399
387
  }
400
388
  xml.required required
401
389
  xml.data_type type
402
- unless variant_of.nil?
403
- xml.variant_of variant_of
404
- end
390
+ xml.variant_of variant_of unless variant_of.nil?
405
391
  unless default_content_path.nil?
406
392
  xml.default_content_path default_content_path
407
393
  end
@@ -410,16 +396,14 @@ class OM::XML::Term
410
396
  xml.absolute xpath
411
397
  xml.constrained xpath_constrained
412
398
  }
413
- if options.fetch(:children, true)
414
- xml.children
415
- end
399
+ xml.children if options.fetch(:children, true)
416
400
  }
417
401
  end
418
402
  doc = builder.doc
419
403
  if options.fetch(:children, true)
420
404
  children.values.each {|child| child.to_xml(options, doc.xpath("//term[@name=\"#{name}\"]/children").first)}
421
405
  end
422
- return doc
406
+ doc
423
407
  end
424
408
 
425
409
  # private :update_xpath_values
@@ -3,12 +3,12 @@ require "logger"
3
3
 
4
4
  class OM::XML::ParentNodeNotFoundError < RuntimeError; end
5
5
  module OM::XML::TermValueOperators
6
-
6
+
7
7
  # Retrieves all of the nodes from the current document that match +term_pointer+ and returns an array of their values
8
8
  def term_values(*term_pointer)
9
9
  result = []
10
10
  xpath = self.class.terminology.xpath_with_indexes(*term_pointer)
11
- #if value is on line by itself sometimes does not trim leading and trailing whitespace for a text node so will detect and fix it
11
+ # if value is on line by itself sometimes does not trim leading and trailing whitespace for a text node so will detect and fix it
12
12
  trim_text = !xpath.nil? && !xpath.index("text()").nil?
13
13
  find_by_terms(*term_pointer).each {|node| result << (trim_text ? node.text.strip : node.text) }
14
14
 
@@ -20,61 +20,59 @@ module OM::XML::TermValueOperators
20
20
  term.deserialize(result)
21
21
  end
22
22
  end
23
-
23
+
24
24
  # alias for term_values
25
25
  def property_values(*lookup_args)
26
26
  term_values(*lookup_args)
27
27
  end
28
-
29
- #
28
+
29
+ #
30
30
  # example term values hash: {[{":person"=>"0"}, "role", "text"]=>{"0"=>"role1", "1"=>"role2", "2"=>"role3"}, [{:person=>1}, :family_name]=>"Andronicus", [{"person"=>"1"},:given_name]=>["Titus"],[{:person=>1},:role,:text]=>["otherrole1","otherrole2"] }
31
31
  def update_values(params={})
32
- # remove any terms from params that this datastream doesn't recognize
33
-
34
- params.delete_if do |term_pointer,new_values|
32
+ # remove any terms from params that this datastream doesn't recognize
33
+
34
+ params.delete_if do |term_pointer,new_values|
35
35
  if term_pointer.kind_of?(String)
36
36
  true
37
37
  else
38
38
  !self.class.terminology.has_term?(*OM.destringify(term_pointer))
39
39
  end
40
40
  end
41
-
41
+
42
42
  result = params.dup
43
-
43
+
44
44
  params.each_pair do |term_pointer,new_values|
45
45
  pointer = OM.destringify(term_pointer)
46
46
  template_pointer = OM.pointers_to_flat_array(pointer,false)
47
47
  hn = OM::XML::Terminology.term_hierarchical_name(*pointer)
48
-
48
+
49
49
  term = self.class.terminology.retrieve_term( *OM.pointers_to_flat_array(pointer,false) )
50
50
 
51
51
  # Sanitize new_values to always be a hash with indexes
52
52
  new_values = term.sanitize_new_values(new_values)
53
-
53
+
54
54
  # Populate the response hash appropriately, using hierarchical names for terms as keys rather than the given pointers.
55
55
  result.delete(term_pointer)
56
56
  result[hn] = new_values.dup
57
-
57
+
58
58
  # Skip any submitted values if the new value matches the current values
59
59
  current_values = term_values(*pointer)
60
60
  new_values.keys.sort { |a,b| a.to_i <=> b.to_i }.each do |y|
61
61
  z = new_values[y]
62
- if current_values[y.to_i]==z and y.to_i > -1
63
- new_values.delete(y)
64
- end
65
- end
66
-
62
+ new_values.delete(y) if current_values[y.to_i]==z && y.to_i > -1
63
+ end
64
+
67
65
  # Fill out the pointer completely if the final term is a NamedTermProxy
68
66
  if term.kind_of? OM::XML::NamedTermProxy
69
67
  pointer.pop
70
68
  pointer = pointer.concat(term.proxy_pointer)
71
69
  end
72
-
70
+
73
71
  xpath = self.class.terminology.xpath_with_indexes(*pointer)
74
72
  parent_pointer = pointer.dup
75
73
  parent_pointer.pop
76
74
  parent_xpath = self.class.terminology.xpath_with_indexes(*parent_pointer)
77
-
75
+
78
76
  # If the value doesn't exist yet, append it. Otherwise, update the existing value.
79
77
  new_values.keys.sort { |a,b| a.to_i <=> b.to_i }.each do |y|
80
78
  z = new_values[y]
@@ -89,18 +87,18 @@ module OM::XML::TermValueOperators
89
87
  end
90
88
  end
91
89
  end
92
- return result
90
+ result
93
91
  end
94
-
92
+
95
93
  def term_values_append(opts={})
96
94
  parent_select = Array( opts[:parent_select] )
97
95
  parent_index = opts[:parent_index]
98
96
  template = opts[:template]
99
- new_values = Array( opts[:values] )
100
-
97
+ new_values = Array( opts[:values] )
98
+
101
99
  parent_nodeset = find_by_terms(*parent_select)
102
100
  parent_node = node_from_set(parent_nodeset, parent_index)
103
-
101
+
104
102
  if parent_node.nil?
105
103
  if parent_select.empty?
106
104
  parent_node = ng_xml.root
@@ -110,12 +108,12 @@ module OM::XML::TermValueOperators
110
108
  end
111
109
 
112
110
  insert_from_template(parent_node, new_values, template)
113
-
114
- return parent_node
115
-
111
+
112
+ parent_node
113
+
116
114
  end
117
115
 
118
- # Insert xml containing +new_values+ into +parent_node+. Generate the xml based on +template+
116
+ # Insert xml containing +new_values+ into +parent_node+. Generate the xml based on +template+
119
117
  # @param [Nokogiri::XML::Node] parent_node to insert new xml into
120
118
  # @param [Array] new_values to build the xml around
121
119
  # @param [Array -- (OM term pointer array) OR String -- (like what you would pass into Nokogiri::XML::Builder.new)] template for building the new xml. Use the syntax that Nokogiri::XML::Builder uses.
@@ -133,23 +131,23 @@ module OM::XML::TermValueOperators
133
131
  template = self.class.terminology.xml_builder_template( *template_args )
134
132
  end
135
133
 
136
- #if there is an xpath element pointing to text() need to change to just 'text' so it references the text method for the parent node
134
+ # if there is an xpath element pointing to text() need to change to just 'text' so it references the text method for the parent node
137
135
  template.gsub!(/text\(\)/, 'text')
138
-
136
+
139
137
  builder = Nokogiri::XML::Builder.with(parent_node) do |xml|
140
138
  new_values.each do |builder_new_value|
141
139
  builder_new_value = builder_new_value.gsub(/'/, "\\\\'") # escape any apostrophes in the new value
142
140
  if matchdata = /xml\.@(\w+)/.match(template)
143
141
  parent_node.set_attribute(matchdata[1], builder_new_value)
144
- else
142
+ else
145
143
  builder_arg = eval('"'+ template + '"') # this inserts builder_new_value into the builder template
146
144
  eval(builder_arg)
147
145
  end
148
146
  end
149
147
  end
150
- return parent_node
148
+ parent_node
151
149
  end
152
-
150
+
153
151
  # Creates necesary ancestor nodes to support inserting a new term value where the ancestor node(s) don't exist yet.
154
152
  # Corrects node indexes in the pointer array to correspond to the ancestors that it creates.
155
153
  # Returns a two-value array with the 'parent' node and a corrected pointer array
@@ -159,20 +157,18 @@ module OM::XML::TermValueOperators
159
157
  parent_select = Array(parent_select)
160
158
  parent_nodeset = find_by_terms(*parent_select)
161
159
  starting_point = node_from_set(parent_nodeset, parent_index)
162
- if starting_point.nil?
163
- starting_point = []
164
- end
160
+ starting_point = [] if starting_point.nil?
165
161
  to_build = []
166
- until !starting_point.empty?
162
+ while starting_point.empty?
167
163
  to_build = [parent_select.pop] + to_build
168
164
  starting_point = find_by_terms(*parent_select)
169
- if starting_point.empty? && parent_select.empty?
165
+ if starting_point.empty? && parent_select.empty?
170
166
  raise OM::XML::TemplateMissingException, "Cannot insert nodes into the document because it is empty. Try defining self.xml_template on the #{self.class} class."
171
167
  end
172
168
  end
173
- to_build.each do |term_pointer|
169
+ to_build.each do |term_pointer|
174
170
  parent_select << term_pointer
175
-
171
+
176
172
  # If pointers in parent_select don't match with the indexes of built ancestors, correct the hash
177
173
  if find_by_terms(*parent_select+[{}]).length == 0
178
174
  if parent_select.last.kind_of?(Hash)
@@ -198,13 +194,13 @@ module OM::XML::TermValueOperators
198
194
  if parent_index > starting_point.length
199
195
  parent_index = starting_point.length - 1
200
196
  end
201
- return node_from_set(starting_point, parent_index)
197
+ node_from_set(starting_point, parent_index)
202
198
  end
203
-
199
+
204
200
  def term_value_update(node_select,node_index,new_value,opts={})
205
201
  ng_xml_will_change!
206
202
  # template = opts.fetch(:template,nil)
207
-
203
+
208
204
  node = find_by_terms_and_value(*node_select)[node_index]
209
205
  if delete_on_update?(node, new_value)
210
206
  node.remove
@@ -216,23 +212,23 @@ module OM::XML::TermValueOperators
216
212
  def delete_on_update?(node, new_value)
217
213
  new_value == "" || new_value == :delete
218
214
  end
219
-
215
+
220
216
  # def term_value_set(term_ref, query_opts, node_index, new_value)
221
217
  # end
222
-
218
+
223
219
  def term_value_delete(opts={})
224
220
  ng_xml_will_change!
225
221
  parent_select = Array( opts[:parent_select] )
226
222
  parent_index = opts[:parent_index]
227
223
  child_index = opts[:child_index]
228
224
  xpath_select = opts[:select]
229
-
225
+
230
226
  if !xpath_select.nil?
231
227
  node = find_by_terms_and_value(xpath_select).first
232
228
  else
233
229
  # parent_nodeset = find_by_terms_and_value(parent_select, parent_select)
234
230
  parent_nodeset = find_by_terms_and_value(*parent_select)
235
-
231
+
236
232
  if parent_index.nil?
237
233
  node = node_from_set(parent_nodeset, child_index)
238
234
  else
@@ -241,24 +237,24 @@ module OM::XML::TermValueOperators
241
237
  node = node_from_set(parent.xpath("*"), child_index)
242
238
  end
243
239
  end
244
-
240
+
245
241
  node.remove
246
242
  end
247
-
248
-
243
+
244
+
249
245
  # Allows you to provide an array index _or_ a symbol representing the function to call on the nodeset in order to retrieve the node.
250
246
  def node_from_set(nodeset, index)
251
247
  if index.kind_of?(Integer)
252
248
  node = nodeset[index]
253
- elsif index.kind_of?(Symbol) && nodeset.respond_to?(index)
249
+ elsif index.kind_of?(Symbol) && nodeset.respond_to?(index)
254
250
  node = nodeset.send(index)
255
251
  else
256
252
  raise "Could not retrieve node using index #{index}."
257
253
  end
258
-
259
- return node
254
+
255
+ node
260
256
  end
261
-
257
+
262
258
  private :node_from_set
263
-
259
+
264
260
  end