om 1.8.0 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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