om 1.8.1 → 1.9.0.pre1

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 (60) hide show
  1. data/Rakefile +1 -1
  2. data/container_spec.rb +14 -14
  3. data/lib/om.rb +12 -9
  4. data/lib/om/samples/mods_article.rb +9 -9
  5. data/lib/om/tree_node.rb +6 -6
  6. data/lib/om/version.rb +1 -1
  7. data/lib/om/xml.rb +33 -31
  8. data/lib/om/xml/container.rb +12 -12
  9. data/lib/om/xml/document.rb +19 -18
  10. data/lib/om/xml/dynamic_node.rb +50 -45
  11. data/lib/om/xml/named_term_proxy.rb +13 -13
  12. data/lib/om/xml/node_generator.rb +3 -3
  13. data/lib/om/xml/template_registry.rb +26 -18
  14. data/lib/om/xml/term.rb +46 -30
  15. data/lib/om/xml/term_value_operators.rb +56 -52
  16. data/lib/om/xml/term_xpath_generator.rb +57 -51
  17. data/lib/om/xml/terminology.rb +10 -8
  18. data/lib/om/xml/terminology_based_solrizer.rb +90 -0
  19. data/lib/om/xml/validation.rb +19 -19
  20. data/lib/om/xml/vocabulary.rb +4 -4
  21. data/lib/tasks/om.rake +6 -4
  22. data/om.gemspec +2 -1
  23. data/spec/fixtures/mods_article.rb +90 -0
  24. data/spec/fixtures/mods_articles/hydrangea_article1.xml +2 -2
  25. data/spec/integration/differentiated_elements_spec.rb +2 -2
  26. data/spec/integration/element_value_spec.rb +13 -13
  27. data/spec/integration/proxies_and_ref_spec.rb +15 -15
  28. data/spec/integration/querying_documents_spec.rb +18 -24
  29. data/spec/integration/rights_metadata_integration_example_spec.rb +18 -18
  30. data/spec/integration/selective_querying_spec.rb +1 -1
  31. data/spec/integration/serialization_spec.rb +13 -13
  32. data/spec/integration/set_reentrant_terminology_spec.rb +10 -10
  33. data/spec/integration/xpathy_stuff_spec.rb +16 -16
  34. data/spec/spec_helper.rb +2 -2
  35. data/spec/unit/container_spec.rb +29 -28
  36. data/spec/unit/document_spec.rb +50 -49
  37. data/spec/unit/dynamic_node_spec.rb +45 -57
  38. data/spec/unit/named_term_proxy_spec.rb +16 -16
  39. data/spec/unit/node_generator_spec.rb +7 -7
  40. data/spec/unit/nokogiri_sanity_spec.rb +30 -30
  41. data/spec/unit/om_spec.rb +5 -5
  42. data/spec/unit/template_registry_spec.rb +69 -69
  43. data/spec/unit/term_builder_spec.rb +77 -77
  44. data/spec/unit/term_spec.rb +73 -79
  45. data/spec/unit/term_value_operators_spec.rb +191 -186
  46. data/spec/unit/term_xpath_generator_spec.rb +43 -37
  47. data/spec/unit/terminology_builder_spec.rb +85 -85
  48. data/spec/unit/terminology_spec.rb +98 -98
  49. data/spec/unit/validation_spec.rb +22 -22
  50. data/spec/unit/xml_serialization_spec.rb +22 -21
  51. data/spec/unit/xml_spec.rb +7 -7
  52. data/spec/unit/xml_terminology_based_solrizer_spec.rb +109 -0
  53. metadata +57 -17
  54. checksums.yaml +0 -7
  55. data/.rspec +0 -1
  56. data/.rubocop.yml +0 -1
  57. data/.rubocop_todo.yml +0 -382
  58. data/.travis.yml +0 -10
  59. data/gemfiles/gemfile.rails3 +0 -11
  60. data/gemfiles/gemfile.rails4 +0 -10
data/Rakefile CHANGED
@@ -13,7 +13,7 @@ task :default => :spec
13
13
 
14
14
  require 'rdoc/task'
15
15
  Rake::RDocTask.new do |rdoc|
16
- version = Om::VERSION
16
+ version = Om::VERSION
17
17
 
18
18
  rdoc.rdoc_dir = 'rdoc'
19
19
  rdoc.title = "om #{version}"
data/container_spec.rb CHANGED
@@ -3,34 +3,34 @@ require "nokogiri"
3
3
  require "om"
4
4
 
5
5
  describe "OM::XML::Container" do
6
-
6
+
7
7
  before(:all) do
8
8
  class ContainerTest
9
9
  include OM::XML::Container
10
10
  end
11
11
  end
12
-
12
+
13
13
  before(:each) do
14
14
  @container = ContainerTest.from_xml("<foo><bar>1</bar></foo>")
15
15
  end
16
-
16
+
17
17
  it "should add .ng_xml accessor" do
18
18
  @container.should respond_to(:ng_xml)
19
- @container.should respond_to(:ng_xml=)
19
+ @container.should respond_to(:ng_xml=)
20
20
  end
21
-
21
+
22
22
  describe "new" do
23
23
  it "should populate ng_xml with an instance of Nokogiri::XML::Document" do
24
24
  @container.ng_xml.class.should == Nokogiri::XML::Document
25
25
  end
26
26
  end
27
-
27
+
28
28
  describe '#xml_template' do
29
29
  it "should return an empty xml document" do
30
30
  ContainerTest.xml_template.to_xml.should == "<?xml version=\"1.0\"?>\n"
31
31
  end
32
32
  end
33
-
33
+
34
34
  describe "#from_xml" do
35
35
  it "should accept a String, parse it and store it in .ng_xml" do
36
36
  Nokogiri::XML::Document.expects(:parse).returns("parsed xml")
@@ -53,36 +53,36 @@ describe "OM::XML::Container" do
53
53
  ContainerTest.from_xml.ng_xml.should == "fake template"
54
54
  end
55
55
  end
56
-
56
+
57
57
  describe ".to_xml" do
58
58
  it "should call .ng_xml.to_xml" do
59
59
  @container.ng_xml.expects(:to_xml).returns("ng xml")
60
60
  @container.to_xml.should == "ng xml"
61
61
  end
62
-
62
+
63
63
  it 'should accept an optional Nokogiri::XML Document as an argument and insert its fields into that (mocked test)' do
64
64
  doc = Nokogiri::XML::Document.parse("<test_xml/>")
65
65
  mock_new_node = mock("new node")
66
66
  doc.root.expects(:add_child).with(@container.ng_xml.root).returns(mock_new_node)
67
67
  result = @container.to_xml(doc)
68
68
  end
69
-
69
+
70
70
  it 'should accept an optional Nokogiri::XML Document as an argument and insert its fields into that (functional test)' do
71
71
  doc = Nokogiri::XML::Document.parse("<test_xml/>")
72
72
  @container.to_xml(doc).should == "<?xml version=\"1.0\"?>\n<test_xml>\n <foo>\n <bar>1</bar>\n </foo>\n</test_xml>\n"
73
73
  end
74
-
74
+
75
75
  it 'should add to root of Nokogiri::XML::Documents, but add directly to the elements if a Nokogiri::XML::Node is passed in' do
76
76
  mock_new_node = mock("new node")
77
77
  mock_new_node.stubs(:to_xml).returns("foo")
78
-
78
+
79
79
  doc = Nokogiri::XML::Document.parse("<test_document/>")
80
80
  el = Nokogiri::XML::Node.new("test_element", Nokogiri::XML::Document.new)
81
81
  doc.root.expects(:add_child).with(@container.ng_xml.root).returns(mock_new_node)
82
82
  el.expects(:add_child).with(@container.ng_xml.root).returns(mock_new_node)
83
- @container.to_xml(doc).should
83
+ @container.to_xml(doc).should
84
84
  @container.to_xml(el)
85
85
  end
86
86
  end
87
-
87
+
88
88
  end
data/lib/om.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'rubygems'
2
- require 'active_model'
2
+ require 'active_support/concern'
3
+ require 'active_model/dirty'
3
4
  require 'deprecation'
4
5
  require 'nokogiri'
5
6
 
@@ -9,7 +10,7 @@ module OM
9
10
  # Converts [{":person"=>"0"}, ":last_name"] to [{:person=>0}, :last_name]
10
11
  def self.destringify(params)
11
12
  case params
12
- when String
13
+ when String
13
14
  if params == "0" || params.to_i != 0
14
15
  result = params.to_i
15
16
  elsif params[0,1] == ":"
@@ -18,13 +19,13 @@ module OM
18
19
  result = params.to_sym
19
20
  end
20
21
  return result
21
- when Hash
22
+ when Hash
22
23
  result = {}
23
24
  params.each_pair do |k,v|
24
25
  result[ destringify(k) ] = destringify(v)
25
26
  end
26
27
  return result
27
- when Array
28
+ when Array
28
29
  result = []
29
30
  params.each do |x|
30
31
  result << destringify(x)
@@ -34,29 +35,31 @@ module OM
34
35
  return params
35
36
  end
36
37
  end
37
-
38
+
38
39
  # Convert a Term pointer into a flat array without Hashes.
39
40
  # If include_indices is set to false, node indices will be removed.
40
41
  #
41
42
  # @param [Array] pointers array that you would pass into other Accessor methods
42
43
  # @param [Boolean] include_indices (default: true) if set to false, parent indices will be excluded from the array
43
44
  # @example Turn a pointer into a flat array with node indices preserved
44
- # OM.pointers_to_flat_array( [{:conference=>0}, {:role=>1}, :text] )
45
+ # OM.pointers_to_flat_array( [{:conference=>0}, {:role=>1}, :text] )
45
46
  # => [:conference, 0, :role, 1, :text]
46
47
  # @example Remove node indices by setting include_indices to false
47
- # OM.pointers_to_flat_array( [{:conference=>0}, {:role=>1}, :text], false )
48
+ # OM.pointers_to_flat_array( [{:conference=>0}, {:role=>1}, :text], false )
48
49
  # => [:conference, :role, :text]
49
50
  def self.pointers_to_flat_array(pointers, include_indices=true)
50
51
  flat_array = []
51
52
  pointers.each do |pointer|
52
53
  if pointer.kind_of?(Hash)
53
54
  flat_array << pointer.keys.first
54
- flat_array << pointer.values.first if include_indices
55
+ if include_indices
56
+ flat_array << pointer.values.first
57
+ end
55
58
  else
56
59
  flat_array << pointer
57
60
  end
58
61
  end
59
- flat_array
62
+ return flat_array
60
63
  end
61
64
 
62
65
  def self.version
@@ -1,7 +1,7 @@
1
1
  class OM::Samples::ModsArticle
2
-
2
+
3
3
  include OM::XML::Document
4
-
4
+
5
5
  set_terminology do |t|
6
6
  t.root(:path=>"mods", :xmlns=>"http://www.loc.gov/mods/v3", :schema=>"http://www.loc.gov/standards/mods/v3/mods-3-2.xsd", "xmlns:foo"=>"http://my.custom.namespace")
7
7
 
@@ -11,17 +11,17 @@ class OM::Samples::ModsArticle
11
11
  t.main_title_lang(:path=>{:attribute=> "xml:lang"})
12
12
  }
13
13
  t.french_title(:ref=>[:title_info,:main_title], :attributes=>{"xml:lang"=>"fre"})
14
-
14
+
15
15
  t.language(:index_as=>[:facetable],:path=>{:attribute=>"lang"})
16
- }
16
+ }
17
17
  t.language{
18
18
  t.lang_code(:index_as=>[:facetable], :path=>"languageTerm", :attributes=>{:type=>"code"})
19
19
  }
20
- t.abstract
20
+ t.abstract
21
21
  t.subject {
22
22
  t.topic(:index_as=>[:facetable])
23
- }
24
- t.topic_tag(:proxy=>[:subject, :topic])
23
+ }
24
+ t.topic_tag(:proxy=>[:subject, :topic])
25
25
  # t.topic_tag(:index_as=>[:facetable],:path=>"subject", :default_content_path=>"topic")
26
26
  # This is a mods:name. The underscore is purely to avoid namespace conflicts.
27
27
  t.name_ {
@@ -40,7 +40,7 @@ class OM::Samples::ModsArticle
40
40
  t.computing_id
41
41
  t.name_content(:path=>"text()")
42
42
  }
43
- # lookup :person, :first_name
43
+ # lookup :person, :first_name
44
44
  t.person(:ref=>:name, :attributes=>{:type=>"personal"}, :index_as=>[:facetable])
45
45
  t.department(:proxy=>[:person,:description],:index_as=>[:facetable])
46
46
  t.organization(:ref=>:name, :attributes=>{:type=>"corporate"}, :index_as=>[:facetable])
@@ -78,7 +78,7 @@ class OM::Samples::ModsArticle
78
78
  t.title(:proxy=>[:title_info, :main_title])
79
79
  t.journal_title(:proxy=>[:journal, :title_info, :main_title])
80
80
  end
81
-
81
+
82
82
  # Changes from OM::Properties implementation
83
83
  # renamed family_name => last_name
84
84
  # start_page & end_page now accessible as [:journal, :issue, :pages, :start] (etc.)
data/lib/om/tree_node.rb CHANGED
@@ -1,23 +1,23 @@
1
1
  module OM::TreeNode
2
-
2
+
3
3
  attr_accessor :ancestors
4
-
4
+
5
5
  # insert the mapper into the given parent
6
6
  def set_parent(parent_mapper)
7
7
  parent_mapper.children[@name] = self
8
8
  @ancestors << parent_mapper
9
9
  end
10
-
10
+
11
11
  # insert the given mapper into the current mappers children
12
12
  def add_child(child_mapper)
13
13
  child_mapper.ancestors << self
14
- @children[child_mapper.name.to_sym] = child_mapper
14
+ @children[child_mapper.name.to_sym] = child_mapper
15
15
  end
16
-
16
+
17
17
  def retrieve_child(child_name)
18
18
  child = @children.fetch(child_name, nil)
19
19
  end
20
-
20
+
21
21
  def parent
22
22
  ancestors.last
23
23
  end
data/lib/om/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Om
2
- VERSION = '1.8.1'
2
+ VERSION = "1.9.0.pre1"
3
3
  end
data/lib/om/xml.rb CHANGED
@@ -1,56 +1,58 @@
1
- require "om/xml/container"
2
- require "om/xml/validation"
3
-
4
- require "om/xml/terminology"
5
- require "om/xml/term"
6
- require "om/xml/term_xpath_generator"
7
- require "om/xml/node_generator"
8
- require "om/xml/term_value_operators"
9
- require "om/xml/named_term_proxy"
10
- require "om/xml/document"
11
- require "om/xml/dynamic_node"
12
-
13
- require "om/xml/template_registry"
14
-
1
+ require 'active_support'
15
2
  module OM::XML
3
+ extend ActiveSupport::Autoload
4
+ autoload :Container
5
+ autoload :Validation
6
+ autoload :Terminology
7
+ autoload :Term
8
+ autoload :TerminologyBasedSolrizer
9
+ autoload :TermXpathGenerator
10
+ autoload :NodeGenerator
11
+ autoload :TermValueOperators
12
+ autoload :NamedTermProxy
13
+ autoload :Document
14
+ autoload :DynamicNode
15
+ autoload :TemplateRegistry
16
16
 
17
17
  # Raised when the XML document or XML template can't be found during an operation
18
18
  class TemplateMissingException < StandardError; end
19
-
19
+
20
20
  attr_accessor :ng_xml
21
-
21
+
22
22
  # Module Methods -- These methods can be called directly on the Module itself
23
-
23
+
24
24
  # Transforms an array of values into a string delimited by +delimiter+
25
25
  def self.delimited_list( values_array, delimiter=", ")
26
26
  values_array.join(delimiter)
27
27
  end
28
-
29
- # Class Methods -- These methods will be available on classes that include this Module
30
-
28
+
29
+ # Class Methods -- These methods will be available on classes that include this Module
30
+
31
31
  module ClassMethods
32
-
32
+
33
33
  # @pointer accessor or property info pointer
34
- #
34
+ #
35
35
  # ex. [[:person,1],:role] will be converted to [{:person=>1},:role]
36
- def sanitize_pointer(pointer)
37
- if pointer.kind_of?(Array)
36
+ def sanitize_pointer(pointer)
37
+ if pointer.kind_of?(Array)
38
38
  pointer.each do |x|
39
- pointer[pointer.index(x)] = Hash[x[0],x[1]] if x.kind_of?(Array)
39
+ if x.kind_of?(Array)
40
+ pointer[pointer.index(x)] = Hash[x[0],x[1]]
41
+ end
40
42
  end
41
43
  end
42
- pointer
44
+ return pointer
43
45
  end
44
-
46
+
45
47
  end
46
-
48
+
47
49
  # Instance Methods -- These methods will be available on instances of classes that include this module
48
-
50
+
49
51
  def self.included(klass)
50
52
  klass.extend(ClassMethods)
51
53
  klass.send(:include, OM::XML::Container)
52
54
  klass.send(:include, OM::XML::Validation)
53
55
  end
54
-
55
-
56
+
57
+
56
58
  end
@@ -1,12 +1,12 @@
1
1
  module OM::XML::Container
2
2
  extend ActiveSupport::Concern
3
-
3
+
4
4
  attr_accessor :ng_xml
5
-
6
- # Class Methods -- These methods will be available on classes that include this Module
7
-
5
+
6
+ # Class Methods -- These methods will be available on classes that include this Module
7
+
8
8
  module ClassMethods
9
-
9
+
10
10
  # @xml String, File or Nokogiri::XML::Node
11
11
  # @tmpl ActiveFedora::MetadataDatastream
12
12
  # Careful! If you call this from a constructor, be sure to provide something 'ie. self' as the @tmpl. Otherwise, you will get an infinite loop!
@@ -18,25 +18,25 @@ module OM::XML::Container
18
18
  else
19
19
  tmpl.ng_xml = Nokogiri::XML::Document.parse(xml)
20
20
  end
21
- tmpl
21
+ return tmpl
22
22
  end
23
-
23
+
24
24
  # By default, new OM Document instances will create an empty xml document, but if you override self.xml_template to return a different object (e.g. Nokogiri::XML::Document), that will be created instead.
25
25
  # You can make this method create the documents however you want as long as it returns a Nokogiri::XML::Document.
26
- # In the tutorials, we use Nokogiri::XML::Builder in this mehtod and call its .doc method at the end of xml_template in order to return the Nokogiri::XML::Document object. Instead of using Nokogiri::XML::Builder, you could put your template into an actual xml file and have xml_template use Nokogiri::XML::Document.parse to load it. That’s up to you.
26
+ # In the tutorials, we use Nokogiri::XML::Builder in this mehtod and call its .doc method at the end of xml_template in order to return the Nokogiri::XML::Document object. Instead of using Nokogiri::XML::Builder, you could put your template into an actual xml file and have xml_template use Nokogiri::XML::Document.parse to load it. That’s up to you.
27
27
  # @return Nokogiri::XML::Document
28
28
  def xml_template
29
29
  Nokogiri::XML::Document.parse("")
30
30
  end
31
-
31
+
32
32
  end
33
-
33
+
34
34
  def ng_xml
35
35
  @ng_xml ||= self.class.xml_template
36
36
  end
37
37
 
38
38
  # Instance Methods -- These methods will be available on instances of classes that include this module
39
-
39
+
40
40
  def to_xml(xml = ng_xml)
41
41
  if xml == ng_xml
42
42
  return xml.to_xml
@@ -52,5 +52,5 @@ module OM::XML::Container
52
52
  raise "You can only pass instances of Nokogiri::XML::Node into this method. You passed in #{xml}"
53
53
  end
54
54
  end
55
-
55
+
56
56
  end
@@ -35,7 +35,7 @@ module OM::XML::Document
35
35
  self.terminology_builder.extend_terminology(&block)
36
36
  rebuild_terminology!
37
37
  end
38
-
38
+
39
39
  # (Explicitly) inherit terminology from upstream classes
40
40
  def use_terminology klass
41
41
  self.terminology_builder = klass.terminology_builder.dup
@@ -69,8 +69,6 @@ module OM::XML::Document
69
69
  end
70
70
 
71
71
  def ng_xml_will_change!
72
- self.dirty = true if self.respond_to?(:dirty=)
73
-
74
72
  # throw away older version.
75
73
  changed_attributes['ng_xml'] = nil
76
74
  end
@@ -79,23 +77,24 @@ module OM::XML::Document
79
77
  changed.include?('ng_xml')
80
78
  end
81
79
 
82
- def method_missing(name, *args)
83
- if matches = /([^=]*)=$/.match(name.to_s)
84
- modified_name = matches[1].to_sym
85
- term = self.class.terminology.retrieve_term(modified_name)
86
- if (term)
87
- node = OM::XML::DynamicNode.new(modified_name, nil, self, term)
88
- node.val=args
89
- else
90
- super
91
- end
92
- else
80
+ def method_missing(method_name, *args)
81
+ if matches = /([^=]+)=$/.match(method_name.to_s)
82
+ name = matches[1].to_sym
83
+ end
84
+
85
+ name ||= method_name
86
+
87
+ begin
93
88
  term = self.class.terminology.retrieve_term(name)
94
- if (term)
95
- OM::XML::DynamicNode.new(name, args.first, self, term)
89
+
90
+ if /=$/.match(method_name.to_s)
91
+ node = OM::XML::DynamicNode.new(name, nil, self, term)
92
+ return node.val=args
96
93
  else
97
- super
94
+ return OM::XML::DynamicNode.new(name, args.first, self, term)
98
95
  end
96
+ rescue OM::XML::Terminology::BadPointerError
97
+ super
99
98
  end
100
99
  end
101
100
 
@@ -194,7 +193,9 @@ module OM::XML::Document
194
193
 
195
194
  private
196
195
  def manipulate_node(method, target, *args, &block)
197
- target = self.find_by_terms(*target) if target.is_a?(Array)
196
+ if target.is_a?(Array)
197
+ target = self.find_by_terms(*target)
198
+ end
198
199
  raise "You must call define_template before calling #{method}" if template_registry.nil?
199
200
  ng_xml_will_change!
200
201
  template_registry.send(method, target, *args, &block)