om 3.0.3 → 3.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1de731732be29cdf0c460beebcb5b603deccb18c
4
+ data.tar.gz: 6fa913f9d7bcdd57e7d29555a266d265dd426ad0
5
+ SHA512:
6
+ metadata.gz: e947f9c90119f8ac601105505d947a2ad78d4307ada79f3f7e609fd64ecb71c0330bbe668438e1d4ee71aac4dbcf112a9f5d2a0fe4a841d9a22125b81cd78e9d
7
+ data.tar.gz: 4db6a2f387c9630f6e9909966bc81e9939110ac92b6588745fb82766ec23d3249041ddbe70b5ddba6322b094622e51cdd09da26365bec6c6af7fcb12cc2a9f5a
@@ -0,0 +1,113 @@
1
+ # How to Contribute
2
+
3
+ We want your help to make Project Hydra great.
4
+ There are a few guidelines that we need contributors to follow so that we can have a chance of keeping on top of things.
5
+
6
+ ## Hydra Project Intellectual Property Licensing and Ownership
7
+
8
+ All code contributors must have an Individual Contributor License Agreement (iCLA) on file with the Hydra Project Steering Group.
9
+ If the contributor works for an institution, the institution must have a Corporate Contributor License Agreement (cCLA) on file.
10
+
11
+ https://wiki.duraspace.org/display/hydra/Hydra+Project+Intellectual+Property+Licensing+and+Ownership
12
+
13
+ You should also add yourself to the `CONTRIBUTORS.md` file in the root of the project.
14
+
15
+ ## Contribution Tasks
16
+
17
+ * Reporting Issues
18
+ * Making Changes
19
+ * Submitting Changes
20
+ * Merging Changes
21
+
22
+ ### Reporting Issues
23
+
24
+ * Make sure you have a [GitHub account](https://github.com/signup/free)
25
+ * Submit a [Github issue](./issues) by:
26
+ * Clearly describing the issue
27
+ * Provide a descriptive summary
28
+ * Explain the expected behavior
29
+ * Explain the actual behavior
30
+ * Provide steps to reproduce the actual behavior
31
+
32
+ ### Making Changes
33
+
34
+ * Fork the repository on GitHub
35
+ * Create a topic branch from where you want to base your work.
36
+ * This is usually the master branch.
37
+ * To quickly create a topic branch based on master; `git branch fix/master/my_contribution master`
38
+ * Then checkout the new branch with `git checkout fix/master/my_contribution`.
39
+ * Please avoid working directly on the `master` branch.
40
+ * You may find the [hub suite of commands](https://github.com/defunkt/hub) helpful
41
+ * Make commits of logical units.
42
+ * Your commit should include a high level description of your work in HISTORY.textile
43
+ * Check for unnecessary whitespace with `git diff --check` before committing.
44
+ * Make sure your commit messages are [well formed](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
45
+ * If you created an issue, you can close it by including "Closes #issue" in your commit message. See [Github's blog post for more details](https://github.com/blog/1386-closing-issues-via-commit-messages)
46
+
47
+ ```
48
+ Present tense short summary (50 characters or less)
49
+
50
+ More detailed description, if necessary. It should be wrapped to 72
51
+ characters. Try to be as descriptive as you can, even if you think that
52
+ the commit content is obvious, it may not be obvious to others. You
53
+ should add such description also if it's already present in bug tracker,
54
+ it should not be necessary to visit a webpage to check the history.
55
+
56
+ Include Closes #<issue-number> when relavent.
57
+
58
+ Description can have multiple paragraphs and you can use code examples
59
+ inside, just indent it with 4 spaces:
60
+
61
+ class PostsController
62
+ def index
63
+ respond_with Post.limit(10)
64
+ end
65
+ end
66
+
67
+ You can also add bullet points:
68
+
69
+ - you can use dashes or asterisks
70
+
71
+ - also, try to indent next line of a point for readability, if it's too
72
+ long to fit in 72 characters
73
+ ```
74
+
75
+ * Make sure you have added the necessary tests for your changes.
76
+ * Run _all_ the tests to assure nothing else was accidentally broken.
77
+ * When you are ready to submit a pull request
78
+
79
+ ### Submitting Changes
80
+
81
+ [Detailed Walkthrough of One Pull Request per Commit](http://ndlib.github.io/practices/one-commit-per-pull-request/)
82
+
83
+ * Read the article ["Using Pull Requests"](https://help.github.com/articles/using-pull-requests) on GitHub.
84
+ * Make sure your branch is up to date with its parent branch (i.e. master)
85
+ * `git checkout master`
86
+ * `git pull --rebase`
87
+ * `git checkout <your-branch>`
88
+ * `git rebase master`
89
+ * It is likely a good idea to run your tests again.
90
+ * Squash the commits for your branch into one commit
91
+ * `git rebase --interactive HEAD~<number-of-commits>` ([See Github help](https://help.github.com/articles/interactive-rebase))
92
+ * To determine the number of commits on your branch: `git log master..<your-branch> --oneline | wc -l`
93
+ * Squashing your branch's changes into one commit is "good form" and helps the person merging your request to see everything that is going on.
94
+ * Push your changes to a topic branch in your fork of the repository.
95
+ * Submit a pull request from your fork to the project.
96
+
97
+ ### Merging Changes
98
+
99
+ * It is considered "poor from" to merge your own request.
100
+ * Please take the time to review the changes and get a sense of what is being changed. Things to consider:
101
+ * Does the commit message explain what is going on?
102
+ * Does the code changes have tests? _Not all changes need new tests, some changes are refactorings_
103
+ * Does the commit contain more than it should? Are two separate concerns being addressed in one commit?
104
+ * Did the Travis tests complete successfully?
105
+ * If you are uncertain, bring other contributors into the conversation by creating a comment that includes their @username.
106
+ * If you like the pull request, but want others to chime in, create a +1 comment and tag a user.
107
+
108
+ # Additional Resources
109
+
110
+ * [General GitHub documentation](http://help.github.com/)
111
+ * [GitHub pull request documentation](http://help.github.com/send-pull-requests/)
112
+ * [Pro Git](http://git-scm.com/book) is both a free and excellent book about Git.
113
+ * [A Git Config for Contributing](http://ndlib.github.io/practices/my-typical-per-project-git-config/)
@@ -1,9 +1,3 @@
1
- h3. 3.0.3 (19 Jul 2013)
2
- Fix overly-aggressive template inheritance bug introduced in 3.0.2
3
-
4
- h3. 3.0.2 (15 Jul 2013)
5
- Add terminology and template inheritance
6
-
7
1
  h3. 3.0.1 (25 Jun 2013)
8
2
  Fix bug where values that were the same as the existing values were
9
3
  removed from the update list
@@ -0,0 +1,41 @@
1
+ [![Build Status](https://travis-ci.org/projecthydra/om.png?branch=master)](https://travis-ci.org/projecthydra/om)
2
+ [![Gem Version](https://badge.fury.io/rb/om.png)](http://badge.fury.io/rb/om)
3
+
4
+ # om (Opinionated Metadata)
5
+
6
+ A library to help you tame sprawling XML schemas like MODS.
7
+
8
+ OM allows you to define a "terminology" to ease translation between XML and ruby objects – you can query the xml for Nodes or node values without ever writing a line of XPath.
9
+
10
+ OM "terms" are ruby symbols you define (in the terminology) that map specific XML content into ruby object attributes.
11
+
12
+ ## Tutorials & Reference
13
+
14
+ * [Tame Your XML with OM](https://github.com/projecthydra/om/wiki/Tame-your-XML-with-OM)
15
+ * [Common OM Patterns](https://github.com/projecthydra/om/blob/master/COMMON_OM_PATTERNS.textile)
16
+
17
+ ### Solrizing Documents
18
+
19
+ The solrizer gem provides support for indexing XML documents into Solr based on OM Terminologies.
20
+ That process is documented in the [solrizer README](https://github.com/projecthydra/solrizer)
21
+
22
+ ## OM in the Wild
23
+
24
+ We have a page on the Hydra wiki with a list of OM Terminologies in active use:
25
+ [OM Terminologies in the Wild](https://wiki.duraspace.org/display/hydra/OM+Terminologies+in+the+Wild)
26
+
27
+ ## Acknowledgments
28
+
29
+ ### Creator
30
+
31
+ Matt Zumwalt ([MediaShelf](http://yourmediashelf.com)
32
+
33
+ ### Thanks To
34
+
35
+ * Bess Sadler, who enabled us to take knowledge gleaned from developing Blacklight and apply it to OM metadata indexing
36
+ * Ross Singer
37
+ * Those who participated in the Opinionated MODS breakout session at Code4Lib 2010
38
+
39
+ ## Copyright
40
+
41
+ Copyright (c) 2010 Matt Zumwalt. See LICENSE for details.
@@ -2,7 +2,7 @@ source "http://rubygems.org"
2
2
 
3
3
  gemspec :path=>"../"
4
4
 
5
- gem 'activemodel', '4.0.0.rc1'
5
+ gem 'activemodel', '~> 4.0.0'
6
6
 
7
7
  group :development, :test do
8
8
  gem 'simplecov', :platform => :mri_19
data/lib/om.rb CHANGED
@@ -65,6 +65,8 @@ module OM
65
65
  def self.version
66
66
  Om::VERSION
67
67
  end
68
+
69
+ class TypeMismatch < StandardError; end
68
70
  end
69
71
 
70
72
  module OM::XML; end
@@ -1,3 +1,3 @@
1
1
  module Om
2
- VERSION = "3.0.3"
2
+ VERSION = "3.0.5"
3
3
  end
@@ -24,7 +24,12 @@ module OM::XML::Document
24
24
  end
25
25
 
26
26
  def terminology_builder
27
- @terminology_builder ||= OM::XML::Terminology::Builder.new
27
+ return @terminology_builder if @terminology_builder
28
+ @terminology_builder = if superclass.respond_to? :terminology_builder
29
+ superclass.terminology_builder.dup
30
+ else
31
+ OM::XML::Terminology::Builder.new
32
+ end
28
33
  end
29
34
 
30
35
  def template_registry
@@ -44,7 +44,7 @@ module OM
44
44
  elsif args.length > 1
45
45
  new_update_node_with_index(name, args)
46
46
  else
47
- child = term_child_by_name(term.nil? ? parent.term : term, name)
47
+ child = term_child_by_name(term.nil? ? parent.term : term, name)
48
48
  if child
49
49
  OM::XML::DynamicNode.new(name, args.first, @document, child, self)
50
50
  else
@@ -53,6 +53,10 @@ module OM
53
53
  end
54
54
  end
55
55
 
56
+ def respond_to?(method)
57
+ super || val.respond_to?(method)
58
+ end
59
+
56
60
  def new_update_node(name, args)
57
61
  modified_name = name.to_s.chop.to_sym
58
62
  child = term.retrieve_term(modified_name)
@@ -97,6 +101,8 @@ module OM
97
101
  end
98
102
  end
99
103
 
104
+ # This resolves the target of this dynamic node into a reified Array
105
+ # @return [Array]
100
106
  def val
101
107
  query = xpath
102
108
  trim_text = !query.index("text()").nil?
@@ -119,7 +125,11 @@ module OM
119
125
  end
120
126
 
121
127
  def ==(other)
122
- val == other
128
+ other == val
129
+ end
130
+
131
+ def !=(other)
132
+ val != other
123
133
  end
124
134
 
125
135
  def eql?(other)
@@ -4,288 +4,291 @@ require 'om/xml/term_builder'
4
4
  # type, index_as, attributes,
5
5
  # is_root_term, required
6
6
  #
7
- class OM::XML::Term
7
+ module OM
8
+ class XML::Term
8
9
 
9
- include OM::TreeNode
10
- include OM::XML::TermBuilder
10
+ include TreeNode
11
+ include XML::TermBuilder
11
12
 
12
- attr_accessor :name, :xpath, :xpath_constrained, :xpath_relative, :path, :index_as, :required, :type, :variant_of, :path, :default_content_path, :is_root_term
13
- attr_accessor :children, :internal_xml, :terminology
13
+ attr_accessor :name, :xpath, :xpath_constrained, :xpath_relative, :path, :index_as, :required, :type, :variant_of, :path, :default_content_path, :is_root_term
14
+ attr_accessor :children, :internal_xml, :terminology
14
15
 
15
- # Any XML attributes that qualify the Term.
16
- #
17
- # @example Declare a Term that has a given attribute (ie. //title[@xml:lang='eng'])
18
- # t.english_title(:path=>"title", :attributes=>{"xml:lang"=>"eng"}
19
- # @example Use nil to point to nodes that do not have a given attribute (ie. //title[not(@xml:lang)])
20
- # t.title_without_lang_attribute(:path=>"title", :attributes=>{"xml:lang"=>nil})
21
- attr_accessor :attributes
16
+ # Any XML attributes that qualify the Term.
17
+ #
18
+ # @example Declare a Term that has a given attribute (ie. //title[@xml:lang='eng'])
19
+ # t.english_title(:path=>"title", :attributes=>{"xml:lang"=>"eng"}
20
+ # @example Use nil to point to nodes that do not have a given attribute (ie. //title[not(@xml:lang)])
21
+ # t.title_without_lang_attribute(:path=>"title", :attributes=>{"xml:lang"=>nil})
22
+ attr_accessor :attributes
22
23
 
23
- # Namespace Prefix (xmlns) for the Term.
24
- #
25
- # By default, OM assumes that all terms in a Terminology have the namespace set in the root of the document. If you want to set a different namespace for a Term, pass :namespace_prefix into its initializer (or call .namespace_prefix= on its builder)
26
- # If a node has _no_ namespace, you must explicitly set namespace_prefix to nil. Currently you have to do this on _each_ term, you can't set namespace_prefix to nil for an entire Terminology.
27
- #
28
- # @example
29
- # # For xml like this
30
- # <foo xmlns="http://foo.com/schemas/fooschema" xmlns:bar="http://bar.com/schemas/barschema">
31
- # <address>1400 Pennsylvania Avenue</address>
32
- # <bar:latitude>56</bar:latitude>
33
- # </foo>
34
- #
35
- # # The Terminology would look like this
36
- # OM::XML::Terminology::Builder.new do |t|
37
- # t.root(:name=>:foo, :path=>"foo", :xmlns=>"http://foo.com/schemas/fooschema", "xmlns:bar"=>"http://bar.com/schemas/barschema")
38
- # t.address
39
- # t.latitude(:namespace_prefix=>"bar")
40
- # end
41
- #
42
- attr_accessor :namespace_prefix
24
+ # Namespace Prefix (xmlns) for the Term.
25
+ #
26
+ # By default, OM assumes that all terms in a Terminology have the namespace set in the root of the document. If you want to set a different namespace for a Term, pass :namespace_prefix into its initializer (or call .namespace_prefix= on its builder)
27
+ # If a node has _no_ namespace, you must explicitly set namespace_prefix to nil. Currently you have to do this on _each_ term, you can't set namespace_prefix to nil for an entire Terminology.
28
+ #
29
+ # @example
30
+ # # For xml like this
31
+ # <foo xmlns="http://foo.com/schemas/fooschema" xmlns:bar="http://bar.com/schemas/barschema">
32
+ # <address>1400 Pennsylvania Avenue</address>
33
+ # <bar:latitude>56</bar:latitude>
34
+ # </foo>
35
+ #
36
+ # # The Terminology would look like this
37
+ # OM::XML::Terminology::Builder.new do |t|
38
+ # t.root(:name=>:foo, :path=>"foo", :xmlns=>"http://foo.com/schemas/fooschema", "xmlns:bar"=>"http://bar.com/schemas/barschema")
39
+ # t.address
40
+ # t.latitude(:namespace_prefix=>"bar")
41
+ # end
42
+ #
43
+ attr_accessor :namespace_prefix
43
44
 
44
45
 
45
- # h2. Namespaces
46
- # By default, OM assumes you have no namespace defined unless it is explicitly defined at the root of your document.
47
- #
48
- # @param [Symbol] name the name to refer to this term by
49
- # @param [Hash] opts
50
- # @option opts [Array] :index_as a list of indexing hints provided to to_solr
51
- # @option opts [String] :path partial xpath that points to the node.
52
- # @option opts [Hash] :attributes xml attributes to match in the selector
53
- # @option opts [String] :namespace_prefix xml namespace for this node. If not provided, the default namespace set in the terminology will be used.
54
- # @option opts [Symbol] :type one of :string, :date, :time :integer. Defaults to :string
55
- def initialize(name, opts={}, terminology=nil)
56
- opts = {:ancestors=>[], :children=>{}}.merge(opts)
57
- [:children, :ancestors,:path, :index_as, :required, :variant_of, :path, :attributes, :default_content_path, :namespace_prefix].each do |accessor_name|
58
- instance_variable_set("@#{accessor_name}", opts.fetch(accessor_name, nil) )
59
- end
46
+ # h2. Namespaces
47
+ # By default, OM assumes you have no namespace defined unless it is explicitly defined at the root of your document.
48
+ #
49
+ # @param [Symbol] name the name to refer to this term by
50
+ # @param [Hash] opts
51
+ # @option opts [Array] :index_as a list of indexing hints provided to to_solr
52
+ # @option opts [String] :path partial xpath that points to the node.
53
+ # @option opts [Hash] :attributes xml attributes to match in the selector
54
+ # @option opts [String] :namespace_prefix xml namespace for this node. If not provided, the default namespace set in the terminology will be used.
55
+ # @option opts [Symbol] :type one of :string, :date, :time :integer. Defaults to :string
56
+ def initialize(name, opts={}, terminology=nil)
57
+ opts = {:ancestors=>[], :children=>{}}.merge(opts)
58
+ [:children, :ancestors,:path, :index_as, :required, :variant_of, :path, :attributes, :default_content_path, :namespace_prefix].each do |accessor_name|
59
+ instance_variable_set("@#{accessor_name}", opts.fetch(accessor_name, nil) )
60
+ end
60
61
 
61
- self.type = opts[:type] || :string
62
+ self.type = opts[:type] || :string
62
63
 
63
- unless terminology.nil?
64
- if opts[:namespace_prefix].nil?
65
- unless terminology.namespaces["xmlns"].nil?
66
- @namespace_prefix = "oxns"
64
+ unless terminology.nil?
65
+ if opts[:namespace_prefix].nil?
66
+ unless terminology.namespaces["xmlns"].nil?
67
+ @namespace_prefix = "oxns"
68
+ end
67
69
  end
68
70
  end
71
+ @name = name
72
+ if @path.nil? || @path.empty?
73
+ @path = name.to_s
74
+ end
69
75
  end
70
- @name = name
71
- if @path.nil? || @path.empty?
72
- @path = name.to_s
73
- end
74
- end
75
76
 
76
77
 
77
- def sanitize_new_values(new_values)
78
- # Sanitize new_values to always be a hash with indexes
79
- case new_values
80
- when Hash
81
- sanitize_new_values(new_values.values)
82
- when Array
83
- new_values.map {|v| serialize(v)}
78
+ def sanitize_new_values(new_values)
79
+ # Sanitize new_values to always be a hash with indexes
80
+ case new_values
81
+ when Hash
82
+ sanitize_new_values(new_values.values)
83
+ when Array
84
+ new_values.map {|v| serialize(v)}
85
+ else
86
+ [serialize(new_values)]
87
+ end
88
+ end
89
+
90
+ # @param val [String,Date,Integer]
91
+ def serialize (val)
92
+ return if val.nil?
93
+ case type
94
+ when :date, :integer
95
+ val.to_s
96
+ when :time
97
+ time = val.to_time
98
+ raise TypeMismatch, "Can't convert `#{val}` to time" if time.nil?
99
+ time.utc.iso8601
100
+ when :boolean
101
+ val.to_s
84
102
  else
85
- [serialize(new_values)]
103
+ val
86
104
  end
87
- end
88
-
89
- # @param val [String,Date,Integer]
90
- def serialize (val)
91
- return if val.nil?
92
- case type
93
- when :date, :integer
94
- val.to_s
95
- when :time
96
- val.to_time.utc.iso8601
97
- when :boolean
98
- val.to_s
99
- else
100
- val
101
105
  end
102
- end
103
106
 
104
- # @param [String] val the value (from xml) to deserialize into the correct object type.
105
- # @return [String,Date,Integer]
106
- def deserialize(val)
107
- case type
108
- when :date
109
- #TODO use present?
110
- val.map { |v| !v.empty? ? Date.parse(v) : nil}
111
- when :time
112
- #TODO use present?
113
- val.map { |v| !v.empty? ? DateTime.parse(v) : nil}
114
- when :integer
115
- #TODO use blank?
116
- val.map { |v| v.empty? ? nil : v.to_i}
117
- when :boolean
118
- val.map { |v| v == 'true' }
119
- else
120
- val
107
+ # @param [String] val the value (from xml) to deserialize into the correct object type.
108
+ # @return [String,Date,Integer]
109
+ def deserialize(val)
110
+ case type
111
+ when :date
112
+ #TODO use present?
113
+ val.map { |v| !v.empty? ? Date.parse(v) : nil}
114
+ when :time
115
+ #TODO use present?
116
+ val.map { |v| !v.empty? ? DateTime.parse(v) : nil}
117
+ when :integer
118
+ #TODO use blank?
119
+ val.map { |v| v.empty? ? nil : v.to_i}
120
+ when :boolean
121
+ val.map { |v| v == 'true' }
122
+ else
123
+ val
124
+ end
121
125
  end
122
- end
123
126
 
124
- def self.from_node(mapper_xml)
125
- name = mapper_xml.attribute("name").text.to_sym
126
- attributes = {}
127
- mapper_xml.xpath("./attribute").each do |a|
128
- attributes[a.attribute("name").text.to_sym] = a.attribute("value").text
129
- end
130
- new_mapper = self.new(name, :attributes=>attributes)
131
- [:index_as, :required, :type, :variant_of, :path, :default_content_path, :namespace_prefix].each do |accessor_name|
132
- attribute = mapper_xml.attribute(accessor_name.to_s)
133
- unless attribute.nil?
134
- new_mapper.instance_variable_set("@#{accessor_name}", attribute.text )
127
+ def self.from_node(mapper_xml)
128
+ name = mapper_xml.attribute("name").text.to_sym
129
+ attributes = {}
130
+ mapper_xml.xpath("./attribute").each do |a|
131
+ attributes[a.attribute("name").text.to_sym] = a.attribute("value").text
135
132
  end
136
- end
137
- new_mapper.internal_xml = mapper_xml
133
+ new_mapper = self.new(name, :attributes=>attributes)
134
+ [:index_as, :required, :type, :variant_of, :path, :default_content_path, :namespace_prefix].each do |accessor_name|
135
+ attribute = mapper_xml.attribute(accessor_name.to_s)
136
+ unless attribute.nil?
137
+ new_mapper.instance_variable_set("@#{accessor_name}", attribute.text )
138
+ end
139
+ end
140
+ new_mapper.internal_xml = mapper_xml
138
141
 
139
- mapper_xml.xpath("./mapper").each do |child_node|
140
- child = self.from_node(child_node)
141
- new_mapper.add_child(child)
142
- end
142
+ mapper_xml.xpath("./mapper").each do |child_node|
143
+ child = self.from_node(child_node)
144
+ new_mapper.add_child(child)
145
+ end
143
146
 
144
- return new_mapper
145
- end
147
+ return new_mapper
148
+ end
146
149
 
147
- ##
148
- # Always co-erce :index_as attributes into an Array
149
- def index_as
150
- Array(@index_as)
151
- end
150
+ ##
151
+ # Always co-erce :index_as attributes into an Array
152
+ def index_as
153
+ Array(@index_as)
154
+ end
152
155
 
153
- # crawl down into mapper's children hash to find the desired mapper
154
- # ie. @test_mapper.retrieve_mapper(:conference, :role, :text)
155
- def retrieve_term(*pointers)
156
- children_hash = self.children
157
- pointers.each do |p|
158
- if children_hash.has_key?(p)
159
- target = children_hash[p]
160
- if pointers.index(p) == pointers.length-1
161
- return target
156
+ # crawl down into mapper's children hash to find the desired mapper
157
+ # ie. @test_mapper.retrieve_mapper(:conference, :role, :text)
158
+ def retrieve_term(*pointers)
159
+ children_hash = self.children
160
+ pointers.each do |p|
161
+ if children_hash.has_key?(p)
162
+ target = children_hash[p]
163
+ if pointers.index(p) == pointers.length-1
164
+ return target
165
+ else
166
+ children_hash = target.children
167
+ end
162
168
  else
163
- children_hash = target.children
169
+ return nil
164
170
  end
165
- else
166
- return nil
167
171
  end
172
+ return target
168
173
  end
169
- return target
170
- end
171
174
 
172
- def is_root_term?
173
- @is_root_term == true
174
- end
175
+ def is_root_term?
176
+ @is_root_term == true
177
+ end
175
178
 
176
- def xpath_absolute
177
- @xpath
178
- end
179
+ def xpath_absolute
180
+ @xpath
181
+ end
179
182
 
180
- # +term_pointers+ reference to the property you want to generate a builder template for
181
- # @param [Hash] extra_opts
182
- # @option extra_opts [Hash] :attributes
183
- def xml_builder_template(extra_opts = {})
184
- extra_attributes = extra_opts.fetch(:attributes, {})
183
+ # +term_pointers+ reference to the property you want to generate a builder template for
184
+ # @param [Hash] extra_opts
185
+ # @option extra_opts [Hash] :attributes
186
+ def xml_builder_template(extra_opts = {})
187
+ extra_attributes = extra_opts.fetch(:attributes, {})
185
188
 
186
- node_options = []
187
- node_child_template = ""
188
- if !self.default_content_path.nil?
189
- node_child_options = ["\':::builder_new_value:::\'"]
190
- node_child_template = " { xml.#{self.default_content_path}( #{OM::XML.delimited_list(node_child_options)} ) }"
191
- else
192
- node_options = ["\':::builder_new_value:::\'"]
193
- end
194
- if !self.attributes.nil?
195
- self.attributes.merge(extra_attributes).each_pair do |k,v|
196
- node_options << "\'#{k}\'=>\'#{v}\'" unless v == :none
189
+ node_options = []
190
+ node_child_template = ""
191
+ if !self.default_content_path.nil?
192
+ node_child_options = ["\':::builder_new_value:::\'"]
193
+ node_child_template = " { xml.#{self.default_content_path}( #{OM::XML.delimited_list(node_child_options)} ) }"
194
+ else
195
+ node_options = ["\':::builder_new_value:::\'"]
196
+ end
197
+ if !self.attributes.nil?
198
+ self.attributes.merge(extra_attributes).each_pair do |k,v|
199
+ node_options << "\'#{k}\'=>\'#{v}\'" unless v == :none
200
+ end
197
201
  end
198
- end
199
202
 
200
- builder_ref = if self.path.include?(":")
201
- "xml['#{self.path[0..path.index(":")-1]}']"
202
- elsif !self.namespace_prefix.nil? and self.namespace_prefix != 'oxns'
203
- "xml['#{self.namespace_prefix}']"
204
- else
205
- "xml"
206
- end
203
+ builder_ref = if self.path.include?(":")
204
+ "xml['#{self.path[0..path.index(":")-1]}']"
205
+ elsif !self.namespace_prefix.nil? and self.namespace_prefix != 'oxns'
206
+ "xml['#{self.namespace_prefix}']"
207
+ else
208
+ "xml"
209
+ end
207
210
 
208
- attribute = OM::XML.delimited_list(node_options)
211
+ attribute = OM::XML.delimited_list(node_options)
209
212
 
210
- builder_method = if self.path.include?(":")
211
- "#{self.path[path.index(":")+1..-1]}( #{attribute} )"
212
- elsif self.path.include?(".")
213
- "send(:\\\"#{self.path}\\\", #{attribute} )"
214
- elsif self.path.kind_of?(Hash) && self.path[:attribute]
215
- "@#{self.path[:attribute]}( #{OM::XML.delimited_list(node_options)} )"
216
- elsif Nokogiri::XML::Builder.method_defined? self.path.to_sym
217
- "#{self.path}_( #{OM::XML.delimited_list(node_options)} )"
218
- else
219
- "#{self.path}( #{OM::XML.delimited_list(node_options)} )"
213
+ builder_method = if self.path.include?(":")
214
+ "#{self.path[path.index(":")+1..-1]}( #{attribute} )"
215
+ elsif self.path.include?(".")
216
+ "send(:\\\"#{self.path}\\\", #{attribute} )"
217
+ elsif self.path.kind_of?(Hash) && self.path[:attribute]
218
+ "@#{self.path[:attribute]}( #{OM::XML.delimited_list(node_options)} )"
219
+ elsif Nokogiri::XML::Builder.method_defined? self.path.to_sym
220
+ "#{self.path}_( #{OM::XML.delimited_list(node_options)} )"
221
+ else
222
+ "#{self.path}( #{OM::XML.delimited_list(node_options)} )"
223
+ end
224
+ template = "#{builder_ref}.#{builder_method}#{node_child_template}"
225
+ return template.gsub( /:::(.*?):::/ ) { '#{'+$1+'}' }
220
226
  end
221
- template = "#{builder_ref}.#{builder_method}#{node_child_template}"
222
- return template.gsub( /:::(.*?):::/ ) { '#{'+$1+'}' }
223
- end
224
227
 
225
- # Generates absolute, relative, and constrained xpaths for the term, setting xpath, xpath_relative, and xpath_constrained accordingly.
226
- # Also triggers update_xpath_values! on all child nodes, as their absolute paths rely on those of their parent nodes.
227
- def generate_xpath_queries!
228
- self.xpath = OM::XML::TermXpathGenerator.generate_absolute_xpath(self)
229
- self.xpath_constrained = OM::XML::TermXpathGenerator.generate_constrained_xpath(self)
230
- self.xpath_relative = OM::XML::TermXpathGenerator.generate_relative_xpath(self)
231
- self.children.each_value {|child| child.generate_xpath_queries! }
232
- return self
233
- end
228
+ # Generates absolute, relative, and constrained xpaths for the term, setting xpath, xpath_relative, and xpath_constrained accordingly.
229
+ # Also triggers update_xpath_values! on all child nodes, as their absolute paths rely on those of their parent nodes.
230
+ def generate_xpath_queries!
231
+ self.xpath = OM::XML::TermXpathGenerator.generate_absolute_xpath(self)
232
+ self.xpath_constrained = OM::XML::TermXpathGenerator.generate_constrained_xpath(self)
233
+ self.xpath_relative = OM::XML::TermXpathGenerator.generate_relative_xpath(self)
234
+ self.children.each_value {|child| child.generate_xpath_queries! }
235
+ return self
236
+ end
234
237
 
235
- # Return an XML representation of the Term
236
- # @param [Hash] options the term will be added to it. If :children=>false, skips rendering child Terms
237
- # @param [Nokogiri::XML::Document] document (optional) document to insert the term xml into
238
- # @return [Nokogiri::XML::Document]
239
- # @example If :children=>false, skips rendering child Terms
240
- # term.to_xml(:children=>false)
241
- # @example You can provide your own Nokogiri document to insert the xml into
242
- # doc = Nokogiri::XML::Document.new
243
- # term.to_xml({}, document=doc)
244
- def to_xml(options={}, document=Nokogiri::XML::Document.new)
245
- builder = Nokogiri::XML::Builder.with(document) do |xml|
246
- xml.term(:name=>name) {
247
- if is_root_term?
248
- xml.is_root_term("true")
249
- end
250
- xml.path path
251
- xml.namespace_prefix namespace_prefix
252
- unless attributes.nil? || attributes.empty?
253
- xml.attributes {
254
- attributes.each_pair do |attribute_name, attribute_value|
255
- xml.send("#{attribute_name}_".to_sym, attribute_value)
238
+ # Return an XML representation of the Term
239
+ # @param [Hash] options the term will be added to it. If :children=>false, skips rendering child Terms
240
+ # @param [Nokogiri::XML::Document] document (optional) document to insert the term xml into
241
+ # @return [Nokogiri::XML::Document]
242
+ # @example If :children=>false, skips rendering child Terms
243
+ # term.to_xml(:children=>false)
244
+ # @example You can provide your own Nokogiri document to insert the xml into
245
+ # doc = Nokogiri::XML::Document.new
246
+ # term.to_xml({}, document=doc)
247
+ def to_xml(options={}, document=Nokogiri::XML::Document.new)
248
+ builder = Nokogiri::XML::Builder.with(document) do |xml|
249
+ xml.term(:name=>name) {
250
+ if is_root_term?
251
+ xml.is_root_term("true")
252
+ end
253
+ xml.path path
254
+ xml.namespace_prefix namespace_prefix
255
+ unless attributes.nil? || attributes.empty?
256
+ xml.attributes {
257
+ attributes.each_pair do |attribute_name, attribute_value|
258
+ xml.send("#{attribute_name}_".to_sym, attribute_value)
259
+ end
260
+ }
261
+ end
262
+ xml.index_as {
263
+ unless index_as.nil?
264
+ index_as.each { |index_type| xml.index_type }
256
265
  end
257
266
  }
258
- end
259
- xml.index_as {
260
- unless index_as.nil?
261
- index_as.each { |index_type| xml.index_type }
267
+ xml.required required
268
+ xml.data_type type
269
+ unless variant_of.nil?
270
+ xml.variant_of variant_of
271
+ end
272
+ unless default_content_path.nil?
273
+ xml.default_content_path default_content_path
274
+ end
275
+ xml.xpath {
276
+ xml.relative xpath_relative
277
+ xml.absolute xpath
278
+ xml.constrained xpath_constrained
279
+ }
280
+ if options.fetch(:children, true)
281
+ xml.children
262
282
  end
263
283
  }
264
- xml.required required
265
- xml.data_type type
266
- unless variant_of.nil?
267
- xml.variant_of variant_of
268
- end
269
- unless default_content_path.nil?
270
- xml.default_content_path default_content_path
271
- end
272
- xml.xpath {
273
- xml.relative xpath_relative
274
- xml.absolute xpath
275
- xml.constrained xpath_constrained
276
- }
277
- if options.fetch(:children, true)
278
- xml.children
279
- end
280
- }
281
- end
282
- doc = builder.doc
283
- if options.fetch(:children, true)
284
- children.values.each {|child| child.to_xml(options, doc.xpath("//term[@name=\"#{name}\"]/children").first)}
284
+ end
285
+ doc = builder.doc
286
+ if options.fetch(:children, true)
287
+ children.values.each {|child| child.to_xml(options, doc.xpath("//term[@name=\"#{name}\"]/children").first)}
288
+ end
289
+ return doc
285
290
  end
286
- return doc
287
- end
288
-
289
- # private :update_xpath_values
290
291
 
292
+ # private :update_xpath_values
293
+ end
291
294
  end