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,27 +1,27 @@
1
1
  require 'loggable'
2
2
  module OM::XML::TermXpathGenerator
3
3
  include Loggable
4
-
4
+
5
5
  # Generate relative xpath for a term
6
6
  # @param [OM::XML::Term] term that you want to generate relative xpath for
7
7
  #
8
8
  # In most cases, the resulting xpath will be the Term's path with the appropriate namespace appended to it.
9
- # If the Term specifies any attributes,
9
+ # If the Term specifies any attributes,
10
10
  # Special Case: attribute Terms
11
- # If the Term's path is set to {:attribute=>attr_name}, the resulting xpath will points to a node attribute named attr_name
11
+ # If the Term's path is set to {:attribute=>attr_name}, the resulting xpath will points to a node attribute named attr_name
12
12
  # ie. a path fo {:attribute=>"lang"} will result in a relative xpath of "@lang"
13
13
  # Special Case: xpath functions
14
14
  # If the Term's path variable is text(), it will be treated as an xpath function (no namespace) and turned into "text()[normalize-space(.)]"
15
15
  def self.generate_relative_xpath(term)
16
16
  template = ""
17
17
  predicates = []
18
-
18
+
19
19
  if term.namespace_prefix.nil?
20
20
  complete_prefix = ""
21
21
  else
22
22
  complete_prefix = term.namespace_prefix + ":"
23
23
  end
24
-
24
+
25
25
  if term.path.kind_of?(Hash)
26
26
  if term.path.has_key?(:attribute)
27
27
  base_path = "@"+term.path[:attribute]
@@ -32,14 +32,12 @@ module OM::XML::TermXpathGenerator
32
32
  if term.path == "text()"
33
33
  base_path = "#{term.path}[normalize-space(.)]"
34
34
  else
35
- unless term.namespace_prefix.nil?
36
- template << complete_prefix
37
- end
35
+ template << complete_prefix unless term.namespace_prefix.nil?
38
36
  base_path = term.path
39
37
  end
40
38
  end
41
39
  template << base_path
42
-
40
+
43
41
  unless term.attributes.nil?
44
42
  term.attributes.each_pair do |attr_name, attr_value|
45
43
  if attr_value == :none
@@ -49,14 +47,14 @@ module OM::XML::TermXpathGenerator
49
47
  end
50
48
  end
51
49
  end
52
-
53
- unless predicates.empty?
50
+
51
+ unless predicates.empty?
54
52
  template << "["+ delimited_list(predicates, " and ")+"]"
55
53
  end
56
-
57
- return template
54
+
55
+ template
58
56
  end
59
-
57
+
60
58
  # Generate absolute xpath for a Term
61
59
  # @param [OM::XML::Term] term that you want to generate absolute xpath for
62
60
  #
@@ -69,36 +67,36 @@ module OM::XML::TermXpathGenerator
69
67
  return term.parent.xpath_absolute + "/" + relative
70
68
  end
71
69
  end
72
-
70
+
73
71
  def self.generate_constrained_xpath(term)
74
72
  if term.namespace_prefix.nil?
75
73
  complete_prefix = ""
76
74
  else
77
75
  complete_prefix = term.namespace_prefix + ":"
78
76
  end
79
-
77
+
80
78
  absolute = generate_absolute_xpath(term)
81
79
  constraint_predicates = []
82
-
80
+
83
81
  arguments_for_contains_function = []
84
82
 
85
- if !term.default_content_path.nil?
83
+ unless term.default_content_path.nil?
86
84
  arguments_for_contains_function << "#{complete_prefix}#{term.default_content_path}"
87
85
  end
88
-
86
+
89
87
  # If no subelements have been specified to search within, set contains function to search within the current node
90
88
  if arguments_for_contains_function.empty?
91
89
  arguments_for_contains_function << "."
92
90
  end
93
-
91
+
94
92
  arguments_for_contains_function << "\":::constraint_value:::\""
95
-
93
+
96
94
  contains_function = "contains(#{delimited_list(arguments_for_contains_function)})"
97
95
 
98
96
  template = add_predicate(absolute, contains_function)
99
- return template.gsub( /:::(.*?):::/ ) { '#{'+$1+'}' }.gsub('"', '\"')
97
+ template.gsub( /:::(.*?):::/ ) { '#{'+$1+'}' }.gsub('"', '\"')
100
98
  end
101
-
99
+
102
100
  # Generate an xpath of the chosen +type+ for the given Term.
103
101
  # @param [OM::XML::Term] term that you want to generate relative xpath for
104
102
  # @param [Symbol] the type of xpath to generate, :relative, :abolute, or :constrained
@@ -112,9 +110,9 @@ module OM::XML::TermXpathGenerator
112
110
  self.generate_constrained_xpath(term)
113
111
  end
114
112
  end
115
-
113
+
116
114
  # Use the given +terminology+ to generate an xpath with (optional) node indexes for each of the term pointers.
117
- # Ex. OM::XML::TermXpathGenerator.xpath_with_indexes(my_terminology, {:conference=>0}, {:role=>1}, :text )
115
+ # Ex. OM::XML::TermXpathGenerator.xpath_with_indexes(my_terminology, {:conference=>0}, {:role=>1}, :text )
118
116
  # will yield an xpath similar to this: '//oxns:name[@type="conference"][1]/oxns:role[2]/oxns:roleTerm[@type="text"]'
119
117
  # @param [OM::XML::Terminology] terminology to generate xpath based on
120
118
  # @param [String -- OM term pointer] pointers identifying the node to generate xpath for
@@ -127,30 +125,28 @@ module OM::XML::TermXpathGenerator
127
125
  return root_term.xpath
128
126
  end
129
127
  end
130
-
128
+
131
129
  query_constraints = nil
132
-
130
+
133
131
  if pointers.length > 1 && pointers.last.kind_of?(Hash)
134
132
  constraints = pointers.pop
135
- unless constraints.empty?
136
- query_constraints = constraints
137
- end
133
+ query_constraints = constraints unless constraints.empty?
138
134
  end
139
135
 
140
136
  if pointers.length == 1 && pointers.first.instance_of?(String)
141
137
  return xpath_query = pointers.first
142
138
  end
143
-
139
+
144
140
  # if pointers.first.kind_of?(String)
145
141
  # return pointers.first
146
142
  # end
147
-
143
+
148
144
  keys = []
149
145
  xpath = "//"
150
146
 
151
147
  pointers = OM.destringify(pointers)
152
148
  pointers.each_with_index do |pointer, pointer_index|
153
-
149
+
154
150
  if pointer.kind_of?(Hash)
155
151
  k = pointer.keys.first
156
152
  index = pointer[k]
@@ -158,13 +154,13 @@ module OM::XML::TermXpathGenerator
158
154
  k = pointer
159
155
  index = nil
160
156
  end
161
-
157
+
162
158
  keys << k
163
-
164
- term = terminology.retrieve_term(*keys)
159
+
160
+ term = terminology.retrieve_term(*keys)
165
161
  # Return nil if there is no term to work with
166
162
  return if term.nil?
167
-
163
+
168
164
  # If we've encountered a NamedTermProxy, insert path sections corresponding to each entry in its proxy_pointer (rather than just the final term that it points to).
169
165
  # TODO Looks like this only works if the last key is a NamedTermProxy, what if we cross proxies on the way there?
170
166
  if term.kind_of? OM::XML::NamedTermProxy
@@ -187,22 +183,20 @@ module OM::XML::TermXpathGenerator
187
183
  raise "There's a problem with the #{term.name} OM::XML::NamedTermProxy, whose proxy pointer is #{term.proxy_pointer}. The #{proxy_pointer} pointer is returning #{proxy_term.inspect}"
188
184
  end
189
185
  end
190
- else
186
+ else
191
187
  relative_path = term.xpath_relative
192
-
188
+
193
189
  unless index.nil?
194
190
  relative_path = add_node_index_predicate(relative_path, index)
195
191
  end
196
192
  end
197
-
198
- if pointer_index > 0
199
- relative_path = "/"+relative_path
200
- end
201
- xpath << relative_path
193
+
194
+ relative_path = "/"+relative_path if pointer_index > 0
195
+ xpath << relative_path
202
196
  end
203
-
204
- final_term = terminology.retrieve_term(*keys)
205
-
197
+
198
+ final_term = terminology.retrieve_term(*keys)
199
+
206
200
  if query_constraints.kind_of?(Hash)
207
201
  contains_functions = []
208
202
  query_constraints.each_pair do |k,v|
@@ -213,20 +207,20 @@ module OM::XML::TermXpathGenerator
213
207
  end
214
208
  contains_functions << "contains(#{constraint_path}, \"#{v}\")"
215
209
  end
216
-
210
+
217
211
  xpath = add_predicate(xpath, delimited_list(contains_functions, " and ") )
218
212
  end
219
-
220
- return xpath
213
+
214
+ xpath
221
215
  end
222
-
216
+
223
217
  # @see OM::XML.delimited_list
224
218
  def self.delimited_list(*args)
225
219
  OM::XML.delimited_list(*args)
226
220
  end
227
-
221
+
228
222
  # Adds xpath xpath node index predicate to the end of your xpath query
229
- # Example:
223
+ # Example:
230
224
  # add_node_index_predicate("//oxns:titleInfo",0)
231
225
  # => "//oxns:titleInfo[1]"
232
226
  #
@@ -236,9 +230,9 @@ module OM::XML::TermXpathGenerator
236
230
  modified_query = xpath_query.dup
237
231
  modified_query << "[#{array_index_value + 1}]"
238
232
  end
239
-
233
+
240
234
  # Adds xpath:position() method call to the end of your xpath query
241
- # Examples:
235
+ # Examples:
242
236
  #
243
237
  # add_position_predicate("//oxns:titleInfo",0)
244
238
  # => "//oxns:titleInfo[position()=1]"
@@ -249,7 +243,7 @@ module OM::XML::TermXpathGenerator
249
243
  position_function = "position()=#{array_index_value + 1}"
250
244
  self.add_predicate(xpath_query, position_function)
251
245
  end
252
-
246
+
253
247
  def self.add_predicate(xpath_query, predicate)
254
248
  modified_query = xpath_query.dup
255
249
  # if xpath_query.include?("]")
@@ -258,7 +252,7 @@ module OM::XML::TermXpathGenerator
258
252
  else
259
253
  modified_query << "[#{predicate}]"
260
254
  end
261
- return modified_query
255
+ modified_query
262
256
  end
263
257
 
264
258
  end
@@ -47,9 +47,7 @@ class OM::XML::Terminology
47
47
  @schema = opts.fetch(:schema,nil)
48
48
  opts.select {|k,v| k.to_s.include?("xmlns")}.each do |ns_pair|
49
49
  @namespaces[ns_pair.first.to_s] = ns_pair.last
50
- if ns_pair.first.to_s == "xmlns"
51
- @namespaces["oxns"] = ns_pair.last
52
- end
50
+ @namespaces["oxns"] = ns_pair.last if ns_pair.first.to_s == "xmlns"
53
51
  end
54
52
  root_term_builder = OM::XML::Term::Builder.new(opts.fetch(:path,:root).to_s.sub(/[_!]$/, '')).is_root_term(true)
55
53
  term_opts = opts.dup
@@ -57,7 +55,7 @@ class OM::XML::Terminology
57
55
  root_term_builder.settings.merge!(term_opts)
58
56
  @term_builders[root_term_builder.name] = root_term_builder
59
57
 
60
- return root_term_builder
58
+ root_term_builder
61
59
  end
62
60
 
63
61
  # Returns an array of Terms that have been marked as "root" terms
@@ -99,7 +97,7 @@ class OM::XML::Terminology
99
97
  raise OM::XML::Terminology::BadPointerError, "You attempted to retrieve a TermBuilder using this pointer: #{args.inspect} but no TermBuilder exists at that location. Everything is fine until \"#{arg.inspect}\", which doesn't exist."
100
98
  end
101
99
  end
102
- return current_term
100
+ current_term
103
101
  end
104
102
 
105
103
  # Add additional terms into this terminology
@@ -137,12 +135,12 @@ class OM::XML::Terminology
137
135
 
138
136
  # Returns true if the current terminology has a term defined at the location indicated by +pointers+ array
139
137
  def has_term?(*pointers)
140
- begin
138
+
141
139
  retrieve_term(*OM.pointers_to_flat_array(pointers, false))
142
140
  return true
143
141
  rescue
144
142
  return false
145
- end
143
+
146
144
  end
147
145
 
148
146
  # Returns the Term corresponding to the given _pointer_.
@@ -160,7 +158,7 @@ class OM::XML::Terminology
160
158
  end
161
159
  end
162
160
  end
163
- return current_term
161
+ current_term
164
162
  end
165
163
 
166
164
  def retrieve_node_subsequent(args, context)
@@ -240,7 +238,7 @@ class OM::XML::Terminology
240
238
  end
241
239
 
242
240
  term = retrieve_term(*term_pointers)
243
- return term.xml_builder_template(extra_opts)
241
+ term.xml_builder_template(extra_opts)
244
242
  end
245
243
 
246
244
  # Returns an array of Terms that have been marked as "root" terms
@@ -274,7 +272,7 @@ class OM::XML::Terminology
274
272
  end
275
273
  document = builder.doc
276
274
  terms.values.each {|term| term.to_xml(options,document.xpath("//terms").first)}
277
- return document
275
+ document
278
276
  end
279
277
 
280
278
  def self.term_generic_name(*pointers)
@@ -1,60 +1,60 @@
1
1
  module OM::XML::Validation
2
2
  extend ActiveSupport::Concern
3
-
4
- # Class Methods -- These methods will be available on classes that include this Module
5
-
3
+
4
+ # Class Methods -- These methods will be available on classes that include this Module
5
+
6
6
  module ClassMethods
7
7
  attr_accessor :schema_url
8
8
  attr_writer :schema_file
9
-
9
+
10
10
  ##
11
11
  # Validation Support
12
12
  ##
13
-
13
+
14
14
  # Validate the given document against the Schema provided by the root_property for this class
15
15
  def validate(doc)
16
16
  schema.validate(doc).each do |error|
17
17
  puts error.message
18
18
  end
19
19
  end
20
-
20
+
21
21
  # Retrieve the Nokogiri Schema for this class
22
22
  def schema
23
23
  @schema ||= Nokogiri::XML::Schema(schema_file.read)
24
24
  end
25
-
25
+
26
26
  # Retrieve the schema file for this class
27
27
  # If the schema file is not already set, it will be loaded from the schema url provided in the root_property configuration for the class
28
28
  def schema_file
29
29
  @schema_file ||= file_from_url(schema_url)
30
30
  end
31
-
31
+
32
32
  # Retrieve file from a url (used by schema_file method to retrieve schema file from the schema url)
33
33
  def file_from_url( url )
34
34
  # parsed_url = URI.parse( url )
35
- #
36
- # if parsed_url.class != URI::HTTP
35
+ #
36
+ # if parsed_url.class != URI::HTTP
37
37
  # raise "Invalid URL. Could not parse #{url} as a HTTP url."
38
38
  # end
39
-
40
- begin
39
+
40
+
41
41
  file = open( url )
42
42
  return file
43
43
  rescue OpenURI::HTTPError => e
44
44
  raise "Could not retrieve file from #{url}. Error: #{e}"
45
- rescue Exception => e
45
+ rescue Exception => e
46
46
  raise "Could not retrieve file from #{url}. Error: #{e}"
47
- end
47
+
48
48
  end
49
-
49
+
50
50
  private :file_from_url
51
-
51
+
52
52
  end
53
-
53
+
54
54
  # Instance Methods -- These methods will be available on instances of classes that include this module
55
-
55
+
56
56
  def validate
57
57
  self.class.validate(self)
58
58
  end
59
-
59
+
60
60
  end
@@ -1,15 +1,15 @@
1
1
  class OM::XML::Vocabulary
2
-
2
+
3
3
  attr_accessor :builder
4
- # Vocabularies are not editable once they've been created because inserting/removing/rearranging mappers in a vocabulary
4
+ # Vocabularies are not editable once they've been created because inserting/removing/rearranging mappers in a vocabulary
5
5
  # will invalidate the xpath queries for an entire branch of the Vocabulary's tree of mappers.
6
6
  # If you want to change a vocabulary's structure, retrieve it's +builder+, make your changes, and re-generate the vocabulary.
7
- #
7
+ #
8
8
  # Ex:
9
9
  # builder = vocabulary.builder
10
10
  # builder.insert_mapper(:name_, :namePart)
11
11
  # vocabulary = builder.build
12
-
12
+
13
13
  # Mappers can be retrieved by their mapper name
14
14
  # Ex.
15
15
  # vocabulary.retrieve_mapper(:name_, :namePart)
data/lib/tasks/om.rake CHANGED
@@ -6,20 +6,18 @@ end
6
6
 
7
7
 
8
8
  desc "Execute specs with coverage"
9
- task :coverage do
9
+ task :coverage do
10
10
  # Put spec opts in a file named .rspec in root
11
11
  ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : "ruby"
12
12
  ENV['COVERAGE'] = 'true' unless ruby_engine == 'jruby'
13
-
14
-
15
13
  Rake::Task['om:rspec'].invoke
16
14
  end
17
15
 
18
- namespace :om do
16
+ namespace :om do
19
17
 
20
18
  require 'rspec/core/rake_task'
21
19
  RSpec::Core::RakeTask.new(:rspec) do |spec|
22
- if ENV['COVERAGE'] and RUBY_VERSION =~ /^1.8/
20
+ if ENV['COVERAGE'] && RUBY_VERSION =~ /^1.8/
23
21
  spec.rcov = true
24
22
  spec.rcov_opts = %w{-I../../app -I../../lib --exclude spec\/*,gems\/*,ruby\/* --aggregate coverage.data}
25
23
  end
@@ -35,7 +33,7 @@ namespace :om do
35
33
  YARD::Rake::YardocTask.new(:doc) do |yt|
36
34
  readme_filename = 'README.textile'
37
35
  textile_docs = []
38
- Dir[File.join(project_root, "*.textile")].each_with_index do |f, index|
36
+ Dir[File.join(project_root, "*.textile")].each_with_index do |f, index|
39
37
  unless f.include?("/#{readme_filename}") # Skip readme, which is already built by the --readme option
40
38
  textile_docs << '-'
41
39
  textile_docs << f