openurl 0.0.1 → 0.1.0

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