openurl 0.0.1 → 0.1.0

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.
@@ -0,0 +1,36 @@
1
+ #
2
+ # journal.rb
3
+ #
4
+ # Created on Nov 1, 2007, 10:35:28 AM
5
+ #
6
+ # To change this template, choose Tools | Templates
7
+ # and open the template in the editor.
8
+
9
+ require 'openurl/metadata_formats/scholarly_common'
10
+ module OpenURL
11
+ class Journal < ScholarlyCommon
12
+
13
+ def initialize
14
+ super()
15
+ @format = 'journal'
16
+ @metadata_keys = ['jtitle','atitle','title','stitle','place','pub','date','edition',
17
+ 'spage','epage', 'pages','issn','eissn', 'isbn','sici','coden','chron',
18
+ 'ssn','quarter','volume','part','issue','artnum'
19
+ ]
20
+ @valid_genres = ["journal","issue","article", "conference","proceeding",
21
+ "preprint","unknown" ]
22
+ @xml_ns = "info:ofi/fmt:xml:xsd:journal"
23
+ @kev_ns = "info:ofi/fmt:kev:mtx:journal"
24
+ end
25
+ end
26
+
27
+ class JournalFactory < ContextObjectEntityFactory
28
+ @@identifiers = ["info:ofi/fmt:kev:mtx:journal","info:ofi/fmt:xml:xsd:journal"]
29
+ def self.identifiers
30
+ return @@identifiers
31
+ end
32
+ def self.create()
33
+ return OpenURL::Journal.new
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,70 @@
1
+ #
2
+ # marc.rb
3
+ #
4
+ # Created on Nov 12, 2007, 10:35:28 AM
5
+ #
6
+ # To change this template, choose Tools | Templates
7
+ # and open the template in the editor.
8
+ require 'rubygems'
9
+ require 'marc'
10
+ module OpenURL
11
+ class Marc < ContextObjectEntity
12
+ private :kev, :set_metadata
13
+ attr_accessor :marc
14
+ def initialize
15
+ super
16
+ @xml_ns = "info:ofi/fmt:xml:xsd:MARC21"
17
+ @format = @xml_ns
18
+ @marc = MARC::Record.new
19
+ @marc_ns = "http://www.loc.gov/MARC21/slim"
20
+ @metadata = @marc.fields
21
+ end
22
+
23
+ def serialize_metadata(elem, label)
24
+ metadata = elem.add_element("ctx:metadata")
25
+ if @marc.is_a?(Array)
26
+ container = metadata.add_elements("#{label}:collection")
27
+ container.add_namespace(label, @marc_ns)
28
+ @marc.each do | mrc |
29
+ rec = mrc.to_xml.root
30
+ mrc_elem = container.add_element rec
31
+ mrc_elem.name = "#{label}:#{mrc_elem.name}"
32
+ end
33
+ else
34
+ rec = @marc.to_xml.root
35
+ rec.add_namespace(label, @marc_ns)
36
+ rec.name = "#{label}:#{rec.name}"
37
+ mrc_elem = metadata.add_element rec
38
+ end
39
+ end
40
+
41
+ def import_xml_metadata(node)
42
+ marcxml = REXML::XPath.first(node,"./ctx:metadata-by-val/ctx:metadata/fmt:collection | ./ctx:metadata-by-val/ctx:metadata/fmt:record",
43
+ {"ctx"=>"info:ofi/fmt:xml:xsd:ctx","fmt"=>@marc_ns})
44
+ if marcxml
45
+ marcxml.root.prefix = ''
46
+ records = []
47
+ MARC::XMLReader.new(StringIO.new(marcxml.to_s)).each do | record |
48
+ records << record
49
+ end
50
+ if records.length == 1
51
+ @marc = records[0]
52
+ else
53
+ @marc = records
54
+ end
55
+ end
56
+ @metadata = @marc.fields
57
+ end
58
+
59
+ end
60
+
61
+ class MarcFactory < ContextObjectEntityFactory
62
+ @@identifiers = ["info:ofi/fmt:xml:xsd:MARC21"]
63
+ def self.identifiers
64
+ return @@identifiers
65
+ end
66
+ def self.create()
67
+ return OpenURL::Marc.new
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,152 @@
1
+ #
2
+ # patent.rb
3
+ #
4
+ # Created on Nov 1, 2007, 10:35:28 AM
5
+ #
6
+ # To change this template, choose Tools | Templates
7
+ # and open the template in the editor.
8
+
9
+ require 'openurl/metadata_formats/scholarly_common'
10
+ module OpenURL
11
+ class Patent < ContextObjectEntity
12
+ attr_reader :inventors
13
+ def initialize
14
+ super
15
+ @format = 'patent'
16
+ @inventors = [OpenURL::Inventor.new]
17
+ @metadata_keys = ['title','co','cc','kind','applcc','applnumber','number',
18
+ 'date','applyear','appldate','assignee','pubdate','prioritydate'
19
+ ]
20
+ @inventor_keys = ['inv', 'invlast', 'invfirst']
21
+ @xml_ns = "info:ofi/fmt:xml:xsd:patent"
22
+ @kev_ns = "info:ofi/fmt:kev:mtx:patent"
23
+ end
24
+
25
+ def method_missing(metadata, value=nil)
26
+ meta = metadata.to_s.sub(/=$/,'')
27
+ raise ArgumentError, "#{meta.to_s} is not a valid #{self.class} metadata field." unless (@inventor_keys+@metadata_keys).index(meta)
28
+ if metadata.to_s.match(/=$/)
29
+ self.set_metadata(meta, value)
30
+ if @inventor_keys.index(meta)
31
+ @inventors[0].instance_variable_set("@#{meta}", value)
32
+ end
33
+ else
34
+ return self.metadata[meta]
35
+ end
36
+
37
+ end
38
+
39
+ def set_metadata(key, val)
40
+ @metadata[key] = val
41
+ if @inventor_keys.index(key)
42
+ @inventors[0].instance_variable_set("@#{key}", val)
43
+ end
44
+ end
45
+
46
+ def add_inventor(inventor)
47
+ raise ArgumentError, "Argument must be an OpenURL::Author!" unless inventor.is_a?(OpenURL::Inventor)
48
+ @inventors << inventor
49
+ end
50
+
51
+ def remove_inventor(inventor)
52
+ idx = inventor
53
+ idx = @inventors.index(inventor)
54
+ raise ArgumentError unless idx
55
+ @authors.delete_at(idx)
56
+ end
57
+
58
+ def serialize_metadata(elem, label)
59
+ meta = {}
60
+ metadata = elem.add_element("ctx:metadata")
61
+ meta["format_container"] = metadata.add_element("#{label}:#{@format}")
62
+ meta["format_container"].add_namespace(label, @xml_ns)
63
+ meta["format_container"].add_attribute("xsi:schemaLocation", "#{@xml_ns} http://www.openurl.info/registry/docs/info:ofi/fmt:xml:xsd:#{@format}")
64
+ @metadata.each do |k,v|
65
+ next if ['inv', 'invlast', 'invfirst'].index(k)
66
+ meta[k] = meta["format_container"].add_element("#{label}:#{k}")
67
+ meta[k].text = v
68
+ end
69
+ meta["inventor_container"] = meta["format_container"].add_element("#{label}:inventors")
70
+ @inventors.each do | inventor |
71
+ inventor.xml(meta["inventor_container"])
72
+ end
73
+ end
74
+ def import_xml_metadata(node)
75
+ mbv = REXML::XPath.first(node, "./ctx:metadata-by-val/ctx:metadata/fmt:#{@format}", {"fmt"=>@xml_ns})
76
+ if mbv
77
+ mbv.to_a.each do |m|
78
+ self.set_metadata(m.name(), m.get_text.value) if m.has_text?
79
+ if m.has_elements?
80
+ m.to_a.each do | md |
81
+ self.set_metadata(md.name(), md.get_text.value) if md.has_text?
82
+ end
83
+ end
84
+ end
85
+ inv_num = 0
86
+ REXML::XPath.each(mbv, "fmt:inventors/fmt:inventor | fmt:inventor/fmt:inv", {"fmt"=>@xml_ns}) do | inventor |
87
+ empty_node = true
88
+ if inventor.name == "inventor"
89
+ inventor.elements.each do | inv_elem |
90
+ next unless @inventor_keys.index(inv_elem.name) and inv_elem.has_text?
91
+ empty_node = false
92
+ @inventors << OpenURL::Inventor.new unless @inventors[inv_num]
93
+ @inventors[inv_num].instance_variable_set("@#{inv_elem.name}".to_sym, inv_elem.get_text.value)
94
+ self.set_metadata(inv_elem.name, inv_elem.get_text.value) if inv_num == 0
95
+ end
96
+ elsif inventor.name.match(/^inv$/)
97
+ next unless inventor.has_text?
98
+ empty_node = false
99
+ @inventors << OpenURL::Inventor.new unless @inventors[inv_num]
100
+ @inventors[inv_num]["inv"] = inventor.get_text.value
101
+ self.set_metadata("inv", inventor.get_text.value) if inv_num == 0
102
+ end
103
+ inv_num += 1 unless empty_node
104
+ end
105
+ end
106
+ end
107
+
108
+ # Outputs the entity as a KEV array
109
+
110
+ def kev(abbr)
111
+ kevs = []
112
+
113
+ @metadata_keys.each do |key|
114
+ kevs << "#{abbr}.#{key}="+CGI.escape(@metadata[key]) if @metadata[key]
115
+ end
116
+
117
+ kevs << "#{abbr}_val_fmt="+CGI.escape(@kev_ns)
118
+
119
+ if @inventors[0] and not @inventors[0].empty?
120
+ @inventor_keys.each do | ikey |
121
+ key = ikey
122
+ key = "inventor" if ikey == "inv"
123
+ kevs << "#{abbr}.#{key}="+CGI.escape(@inventors[0].ikey) if @inventors[0].ikey
124
+ end
125
+
126
+ end
127
+
128
+ if @reference["format"]
129
+ kevs << "#{abbr}_ref_fmt="+CGI.escape(@reference["format"])
130
+ kevs << "#{abbr}_ref="+CGI.escape(@reference["location"])
131
+ end
132
+
133
+ @identifiers.each do |id|
134
+ kevs << "#{abbr}_id="+CGI.escape(id)
135
+ end
136
+
137
+ kevs << "#{abbr}_dat="+CGI.escape(@private_data) if @private_data
138
+
139
+ return kevs
140
+ end
141
+ end
142
+
143
+ class PatentFactory < ContextObjectEntityFactory
144
+ @@identifiers = ["info:ofi/fmt:kev:mtx:patent","info:ofi/fmt:xml:xsd:patent"]
145
+ def self.identifiers
146
+ return @@identifiers
147
+ end
148
+ def self.create()
149
+ return OpenURL::Patent.new
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,198 @@
1
+ #
2
+ # scholarly_common.rb
3
+ #
4
+ # Created on Nov 5, 2007, 3:24:35 PM
5
+ #
6
+ # To change this template, choose Tools | Templates
7
+ # and open the template in the editor.
8
+
9
+
10
+ module OpenURL
11
+ class ScholarlyCommon < ContextObjectEntity
12
+ attr_reader :authors
13
+ def initialize
14
+ super()
15
+ @authors = [OpenURL::Author.new]
16
+ @author_keys = ['aulast','aufirst','auinit','auinit1','auinitm','ausuffix',
17
+ 'au', 'aucorp']
18
+ end
19
+ def method_missing(metadata, value=nil)
20
+ meta = metadata.to_s.sub(/=$/,'')
21
+ raise ArgumentError, "#{meta.to_s} is not a valid #{self.class} metadata field." unless (@author_keys+@metadata_keys).index(meta)
22
+ if metadata.to_s.match(/=$/)
23
+ self.set_metadata(meta, value)
24
+ if @author_keys.index(meta)
25
+ @authors[0].instance_variable_set("@#{meta}", value)
26
+ end
27
+ else
28
+ return self.metadata[meta]
29
+ end
30
+
31
+ end
32
+
33
+ def set_metadata(key, val)
34
+ @metadata[key] = val.to_s
35
+ if @author_keys.index(key)
36
+ @authors[0].instance_variable_set("@#{key}", val)
37
+ end
38
+ end
39
+
40
+ def genre=(genre)
41
+ raise ArgumentError, "#{genre} is not a valid #{self.class} genre." unless @valid_genres.index(genre)
42
+ self.set_metadata('genre', genre)
43
+ end
44
+
45
+ def genre
46
+ return self.metadata["genre"]
47
+ end
48
+
49
+ def add_author(author)
50
+ raise ArgumentError, "Argument must be an OpenURL::Author!" unless author.is_a?(OpenURL::Author)
51
+ @authors << author
52
+ end
53
+
54
+ def remove_author(author)
55
+ idx = author
56
+ idx = @authors.index(author)
57
+ raise ArgumentError unless idx
58
+ @authors.delete_at(idx)
59
+ end
60
+
61
+ def serialize_metadata(elem, label)
62
+ meta = {}
63
+ metadata = elem.add_element("ctx:metadata")
64
+ meta["format_container"] = metadata.add_element("#{label}:#{@format}")
65
+ meta["format_container"].add_namespace(label, @xml_ns)
66
+ meta["format_container"].add_attribute("xsi:schemaLocation", "#{@xml_ns} http://www.openurl.info/registry/docs/info:ofi/fmt:xml:xsd:#{@format}")
67
+ @metadata.each do |k,v|
68
+ next if ['au', 'aucorp', 'auinit', 'auinitm', 'aulast',
69
+ 'aufirst', 'auinit1', 'ausuffix'].index(k)
70
+ meta[k] = meta["format_container"].add_element("#{label}:#{k}")
71
+ meta[k].text = v
72
+ end
73
+ meta["author_container"] = meta["format_container"].add_element("#{label}:authors")
74
+ @authors.each do | author |
75
+ author.xml(meta["author_container"])
76
+ end
77
+ end
78
+
79
+ def import_xml_metadata(node)
80
+ mbv = REXML::XPath.first(node, "./ctx:metadata-by-val/ctx:metadata/fmt:#{@format}", {"ctx"=>"info:ofi/fmt:xml:xsd:ctx", "fmt"=>@xml_ns})
81
+ if mbv
82
+ mbv.to_a.each do |m|
83
+ self.set_metadata(m.name(), m.get_text.value) if m.has_text?
84
+ if m.has_elements?
85
+ m.to_a.each do | md |
86
+ self.set_metadata(md.name(), md.get_text.value) if md.has_text?
87
+ end
88
+ end
89
+ end
90
+ auth_num = 0
91
+ REXML::XPath.each(mbv, "fmt:authors/fmt:author | fmt:authors/fmt:au | fmt:authors/fmt:aucorp", {"fmt"=>@xml_ns}) do | author |
92
+ empty_node = true
93
+ if author.name == "author"
94
+ author.elements.each do | auth_elem |
95
+ next unless @author_keys.index(auth_elem.name) and auth_elem.has_text?
96
+ empty_node = false
97
+ @authors << OpenURL::Author.new unless @authors[auth_num]
98
+ @authors[auth_num].instance_variable_set("@#{auth_elem.name}".to_sym, auth_elem.get_text.value)
99
+ self.set_metadata(auth_elem.name, auth_elem.get_text.value) if auth_num == 0
100
+ end
101
+ elsif author.name.match(/^au$|^aucorp$/)
102
+ next unless author.has_text?
103
+ empty_node = false
104
+ @authors << OpenURL::Author.new unless @authors[auth_num]
105
+ # This next line is causing an exception, replaced it with following line modeling from above clause. Don't entirely understand it.
106
+ # @authors[auth_num][author.name] = author.get_text.value
107
+ @authors[auth_num].instance_variable_set("@#{author.name}".to_sym, author.get_text.value)
108
+ self.set_metadata(author.name, author.get_text.value) if auth_num == 0
109
+ end
110
+ auth_num += 1 unless empty_node
111
+ end
112
+ end
113
+ end
114
+ end
115
+
116
+ class Author
117
+ attr_accessor :aulast, :aufirst, :auinit, :auinit1, :auinitm, :ausuffix,
118
+ :au, :aucorp
119
+ def initialize
120
+ end
121
+
122
+ def xml(elem)
123
+ if @au
124
+ au = elem.add_element("#{elem.prefix}:au")
125
+ au.text = @au
126
+ end
127
+ if @aucorp
128
+ aucorp = elem.add_element("#{elem.prefix}:aucorp")
129
+ aucorp.text = @aucorp
130
+ end
131
+ if @aulast || @aufirst || @auinit || @auinit1 || @auinitm || @ausuffix
132
+ author = elem.add_element("#{elem.prefix}:author")
133
+ if @aulast
134
+ aulast = author.add_element("#{elem.prefix}:aulast")
135
+ aulast.text = @aulast
136
+ end
137
+ if @aufirst
138
+ aufirst = author.add_element("#{elem.prefix}:aufirst")
139
+ aufirst.text = @aufirst
140
+ end
141
+ if @auinit
142
+ auinit = author.add_element("#{elem.prefix}:auinit")
143
+ auinit.text = @auinit
144
+ end
145
+ if @auinit1
146
+ auinit1 = author.add_element("#{elem.prefix}:auinit1")
147
+ auinit1.text = @auinit1
148
+ end
149
+ if @auinitm
150
+ auinitm = author.add_element("#{elem.prefix}:auinitm")
151
+ auinitm.text = @auinitm
152
+ end
153
+ if @ausuffix
154
+ ausuff = author.add_element("#{elem.prefix}:ausuffix")
155
+ ausuff.text = @ausuffix
156
+ end
157
+ end
158
+ end
159
+
160
+ def empty?
161
+ self.instance_variables.each do | ivar |
162
+ return false if self.instance_variable_get(ivar)
163
+ end
164
+ return true
165
+ end
166
+ end
167
+
168
+ class Inventor
169
+ attr_accessor :invlast, :invfirst, :inv
170
+ def initialize
171
+ end
172
+
173
+ def xml(elem)
174
+ if @inv
175
+ inv = elem.add_element("#{elem.prefix}:inv")
176
+ inv.text = @inv
177
+ end
178
+ if @invlast || @invfirst
179
+ inventor = elem.add_element("#{elem.prefix}:inventor")
180
+ if @invlast
181
+ invlast = inventor.add_element("#{elem.prefix}:invlast")
182
+ invlast.text = @invlast
183
+ end
184
+ if @invfirst
185
+ invfirst = inventor.add_element("#{elem.prefix}:invfirst")
186
+ invfirst.text = @invfirst
187
+ end
188
+ end
189
+ end
190
+
191
+ def empty?
192
+ self.instance_variables.each do | ivar |
193
+ return false if self.instance_variable_get(ivar)
194
+ end
195
+ return true
196
+ end
197
+ end
198
+ end