om 1.8.1 → 1.9.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
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)