marc4j4r 0.1.6 → 0.2.2

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 (54) hide show
  1. data/README.rdoc +17 -0
  2. data/Rakefile +26 -13
  3. data/VERSION +1 -1
  4. data/jars/marc4j.jar +0 -0
  5. data/lib/marc4j4r/controlfield.rb +32 -0
  6. data/lib/marc4j4r/datafield.rb +196 -0
  7. data/lib/marc4j4r/reader.rb +71 -0
  8. data/lib/marc4j4r/record.rb +214 -0
  9. data/lib/marc4j4r/writer.rb +29 -0
  10. data/lib/marc4j4r.rb +26 -485
  11. data/lib/original_monolithic_file.rb +518 -0
  12. data/spec/batch.dat +1 -0
  13. data/spec/batch.txt +193 -0
  14. data/spec/batch.xml +13 -0
  15. data/spec/controlfield_spec.rb +40 -0
  16. data/spec/datafield_spec.rb +56 -0
  17. data/spec/one.dat +1 -0
  18. data/spec/one.txt +17 -0
  19. data/spec/one.xml +4 -0
  20. data/spec/reader_spec.rb +49 -0
  21. data/spec/record_spec.rb +101 -0
  22. data/{test/helper.rb → spec/spec_helper.rb} +9 -5
  23. metadata +74 -80
  24. data/.document +0 -5
  25. data/.gitignore +0 -21
  26. data/README.markdown +0 -41
  27. data/doc/ControlFieldImpl.html +0 -314
  28. data/doc/DataFieldImpl.html +0 -875
  29. data/doc/Java/OrgMarc4j/MarcReader.html +0 -184
  30. data/doc/MARC4J4R/Reader.html +0 -245
  31. data/doc/MARC4J4R.html +0 -281
  32. data/doc/RecordImpl.html +0 -686
  33. data/doc/SubfieldImpl.html +0 -252
  34. data/doc/_index.html +0 -153
  35. data/doc/class_list.html +0 -36
  36. data/doc/css/common.css +0 -1
  37. data/doc/css/full_list.css +0 -50
  38. data/doc/css/style.css +0 -268
  39. data/doc/file.README.html +0 -90
  40. data/doc/file_list.html +0 -38
  41. data/doc/frames.html +0 -13
  42. data/doc/index.html +0 -90
  43. data/doc/js/app.js +0 -99
  44. data/doc/js/full_list.js +0 -106
  45. data/doc/js/jquery.js +0 -19
  46. data/doc/method_list.html +0 -219
  47. data/doc/top-level-namespace.html +0 -87
  48. data/jars/MarcImporter.jar +0 -0
  49. data/test/batch.seq +0 -118
  50. data/test/bench.rb +0 -63
  51. data/test/one.dat +0 -1
  52. data/test/one.seq +0 -30
  53. data/test/one.xml +0 -55
  54. data/test/test_marc4j4r.rb +0 -76
data/README.rdoc ADDED
@@ -0,0 +1,17 @@
1
+ = marc4j4r
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 BillDueber. See LICENSE for details.
data/Rakefile CHANGED
@@ -1,16 +1,17 @@
1
1
  require 'rubygems'
2
2
  require 'rake'
3
+ require 'ftools'
3
4
 
4
5
  begin
5
6
  require 'jeweler'
6
7
  Jeweler::Tasks.new do |gem|
7
8
  gem.name = "marc4j4r"
8
9
  gem.summary = %Q{Use marc4j java library in JRuby in a more ruby-ish way}
9
- gem.description = %Q{Syntactic sugar and some extra methods to deal with classes in the marc4j java package}
10
+ gem.description = %Q{Syntactic sugar and some extra methods to deal with MARC data using the java .jar marc4j}
10
11
  gem.email = "bill@dueber.com"
11
- gem.homepage = "http://github.com/billdueber/marc4j4r"
12
+ gem.homepage = "http://github.com/billdueber/javamarc/tree/master/ruby/marc4j4r/"
12
13
  gem.authors = ["BillDueber"]
13
- gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
14
+ gem.add_development_dependency "bacon", ">= 0"
14
15
  gem.add_development_dependency "yard", ">= 0"
15
16
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
17
  end
@@ -19,19 +20,31 @@ rescue LoadError
19
20
  puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
20
21
  end
21
22
 
23
+
24
+ # Make sure we've got the right .jar
25
+ LOCALJAR = 'jars/marc4j.jar'
26
+ JAVAJAR = '../../marc4j.jar'
27
+
28
+
29
+ file LOCALJAR => JAVAJAR do |t|
30
+ File.copy(JAVAJAR, LOCALJAR)
31
+ end
32
+
33
+
34
+
22
35
  require 'rake/testtask'
23
- Rake::TestTask.new(:test) do |test|
24
- test.libs << 'lib' << 'test'
25
- test.pattern = 'test/**/test_*.rb'
26
- test.verbose = true
36
+ Rake::TestTask.new(:spec) do |spec|
37
+ spec.libs << 'lib' << 'spec'
38
+ spec.pattern = 'spec/**/*_spec.rb'
39
+ spec.verbose = true
27
40
  end
28
41
 
29
42
  begin
30
43
  require 'rcov/rcovtask'
31
- Rcov::RcovTask.new do |test|
32
- test.libs << 'test'
33
- test.pattern = 'test/**/test_*.rb'
34
- test.verbose = true
44
+ Rcov::RcovTask.new do |spec|
45
+ spec.libs << 'spec'
46
+ spec.pattern = 'spec/**/*_spec.rb'
47
+ spec.verbose = true
35
48
  end
36
49
  rescue LoadError
37
50
  task :rcov do
@@ -39,9 +52,9 @@ rescue LoadError
39
52
  end
40
53
  end
41
54
 
42
- task :test => :check_dependencies
55
+ task :spec => [:check_dependencies, LOCALJAR]
43
56
 
44
- task :default => :test
57
+ task :default => :spec
45
58
 
46
59
  begin
47
60
  require 'yard'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.6
1
+ 0.2.2
data/jars/marc4j.jar CHANGED
Binary file
@@ -0,0 +1,32 @@
1
+ module MARC4J4R
2
+ ControlField = Java::org.marc4j.marc.impl::ControlFieldImpl
3
+ class ControlField
4
+ def value
5
+ return self.data
6
+ end
7
+
8
+ def value= str
9
+ self.data = str
10
+ end
11
+
12
+ def controlField?
13
+ return true
14
+ end
15
+
16
+ def self.control_tag? tag
17
+ return Java::org.marc4j.marc.impl.Verifier.isControlField tag
18
+ end
19
+
20
+ # Pretty-print
21
+ # @param [String] joiner What string to use to join the subfields
22
+ # @param [String] The pretty string
23
+ def to_s
24
+ return self.tag + " " + self.value
25
+ end
26
+
27
+ def == other
28
+ self.tag == other.tag && self.value == other.value
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,196 @@
1
+ module MARC4J4R
2
+ DataField = Java::org.marc4j.marc.impl::DataFieldImpl
3
+ SubField = Java::org.marc4j.marc.impl::SubfieldImpl
4
+
5
+ class DataField
6
+ include Enumerable
7
+
8
+ alias_method :<<, :addSubfield
9
+ alias_method :add, :addSubfield
10
+
11
+ # Override the initialize to allow creation with just a tag (marc4j only allows either
12
+ # no args or the tag and both indicators)
13
+
14
+ alias_method :oldinit, :initialize
15
+ def initialize(tag = nil, ind1 = ' ', ind2 = ' ')
16
+ if tag
17
+ self.oldinit(tag, ind1[0].ord, ind2[0].ord)
18
+ else
19
+ self.oldinit
20
+ end
21
+ end
22
+
23
+ def controlField?
24
+ return false
25
+ end
26
+
27
+ def == other
28
+
29
+ basics = ((self.tag == other.tag) and (self.indicator1 == other.indicator1) and (self.indicator2 == other.indicator2))
30
+ unless basics
31
+ # puts "Failed basics"
32
+ return false
33
+ end
34
+ selfsubs = self.to_a
35
+ othersubs = other.to_a
36
+ # puts "#{self} vs #{other}"
37
+ while (selfsubs.length > 0)
38
+ ssf = selfsubs.shift
39
+ osf = othersubs.shift
40
+ unless ssf == osf
41
+ # puts "#{ssf} <> #{osf}"
42
+ return false
43
+ end
44
+ end
45
+
46
+ if ((selfsubs.size > 0) or (othersubs.size > 0))
47
+ # puts "sizes unequal"
48
+ return false
49
+ end
50
+ return true
51
+ end
52
+
53
+ # Pretty-print
54
+ # @param [String] joiner What string to use to join the subfields
55
+ # @param [String] The pretty string
56
+ def to_s (joiner = ' ')
57
+ arr = [self.tag + ' ' + self.indicator1 + self.indicator2]
58
+ self.each do |s|
59
+ arr.push s.to_s
60
+ end
61
+ return arr.join(joiner)
62
+ end
63
+
64
+
65
+ # Get the value of the first subfield of this field with the given code
66
+ # @param [String] code 1-character string of the subfield code
67
+ # @return [String] The value of the first matched subfield
68
+ def [] code
69
+ raise ArgumentError, "Code must be a one-character string, not #{code}" unless code.is_a? String and code.size == 1
70
+ # need to send a char value that the underlying java can deal with
71
+ sub = self.getSubfield(code[0].ord)
72
+ if (sub)
73
+ return sub.getData
74
+ else
75
+ return nil
76
+ end
77
+ end
78
+
79
+ # Also call it "sub" for symmatry wtih "sub_values" and "subs"
80
+ # and "first" because it makes sense
81
+ alias_method :sub, :[]
82
+ alias_method :first, :[]
83
+
84
+ # Get all subfields, optionally restricting to those with a given code
85
+ # @param [String, Array<String>] code A (array of?) 1-character strings; the code(s) to collect. Default is all
86
+ # @return [Array<MARC4J4R::SubField] The matching subfields, or an empty array
87
+
88
+ def subs code = false
89
+ unless code
90
+ return self.to_a
91
+ end
92
+
93
+ # Is it a singleton?
94
+ if not [Set, Array].include? code.class
95
+ code = [code]
96
+ end
97
+
98
+ return self.grep {|s| code.include? s.code}
99
+ end
100
+
101
+ # Get all values from the subfields for the given code or array of codes
102
+ # @param [String, Array<String>] code (Array of?) 1-character string(s) of the subfield code
103
+ # @return [Array<String>] A possibly-empty array of Strings made up of the values in the subfields whose
104
+ # code is included in the given codes (or all subfields is code is empty)
105
+ #
106
+ #
107
+ # @example Quick examples:
108
+ # # 260 $a New York, $b Van Nostrand Reinhold Co. $c 1969
109
+ # rec['260'].sub_values('a') #=> ["New York,"]
110
+ # rec['260'].sub_values(['a', 'c']) #=> ["New York,", "1969"]
111
+ # rec['260'].sub_values(['c', 'a']) #=> ["New York,", "1969"]
112
+
113
+ def sub_values(code)
114
+ return self.subs(code).collect {|s| s.value}
115
+ end
116
+
117
+
118
+ # Get first indicator as a one-character string
119
+ def indicator1
120
+ return self.getIndicator1.chr
121
+ end
122
+
123
+ # Get second indicator as a one-character string
124
+ def indicator2
125
+ return self.getIndicator2.chr
126
+ end
127
+
128
+ def indicator1= char
129
+ self.setIndicator1 char[0].ord
130
+ end
131
+
132
+ def indicator2= char
133
+ self.setIndicator2 char[0].ord
134
+ end
135
+
136
+ alias_method :ind1, :indicator1
137
+ alias_method :"ind1=", :"indicator1="
138
+ alias_method :ind2, :indicator2
139
+ alias_method :"ind2=", :"indicator2="
140
+
141
+ # Iterate over the subfields
142
+ def each
143
+ self.getSubfields.each do |s|
144
+ yield s
145
+ end
146
+ end
147
+
148
+ # Get the concatentated values of the subfields in order the appear in the field
149
+ # @param [String] joiner The string used to join the subfield values
150
+ def value joiner=' '
151
+ data = self.getSubfields.map {|s| s.data}
152
+ return data.join(joiner)
153
+ end
154
+ end
155
+
156
+ class SubField
157
+
158
+ alias_method :oldinit, :initialize
159
+ def initialize code=nil, data=nil
160
+ if code
161
+ code = code[0].ord
162
+ if data
163
+ self.oldinit(code, data)
164
+ else
165
+ self.oldinit(code)
166
+ end
167
+ else
168
+ self.oldinit
169
+ end
170
+ end
171
+
172
+ def == other
173
+ return ((self.code == other.code) and (self.data == other.data))
174
+ end
175
+
176
+ def value
177
+ return self.data
178
+ end
179
+
180
+ def value= str
181
+ self.data = str
182
+ end
183
+
184
+ def code
185
+ return self.getCode.chr
186
+ end
187
+
188
+ def code= str
189
+ self.setCode str[0].ord
190
+ end
191
+
192
+ def to_s
193
+ return '$' + self.code + " " + self.data
194
+ end
195
+ end
196
+ end
@@ -0,0 +1,71 @@
1
+ module Java::OrgMarc4j::MarcReader
2
+ include Enumerable
3
+
4
+ # Return the next record, after calling #hashify on it
5
+ def each(hashify=true)
6
+ while self.hasNext
7
+ r = self.next
8
+ r.hashify if hashify
9
+ yield r
10
+ end
11
+ end
12
+ end
13
+
14
+
15
+ module MARC4J4R
16
+ # Add some sugar to the MarcReader interface
17
+ #
18
+ # Adjust the interface so that a #new call to any implementations that
19
+ # implement it can take a java.io.InputStream, ruby IO obejct, or String
20
+ # (that will be interpreted as a filename) without complaining.
21
+ #
22
+ # The mechanism -- running module_eval on a string-representation of the
23
+ # new method in each of the hard-coded implementations of MarcReader
24
+ # (MarcStreamReader,MarcPermissiveStreamReader,MarcXmlReader) -- is ugly
25
+ # and deeply unsettling.
26
+ #
27
+ # @author Bill Dueber
28
+
29
+ # First, add Enumerable to the interface
30
+ Java::org.marc4j.MarcReader.module_eval("include Enumerable")
31
+
32
+
33
+ class Reader
34
+
35
+ # Get a marc reader of the appropriate type
36
+ # @param [String, IO, java.io.InputStream] input The IO stream (or filename) from which you want to read
37
+ # @param [:strictmarc, :permissivemarc, :marcxml] The type of MARC reader you want.
38
+ # @return [MarcReader] A MarcReader object with the syntactic sugar added in this file (e.g, each)
39
+ #
40
+ # @example Get a strict binary MARC reader for the file 'test.mrc'
41
+ # reader = MARC4J4R::Reader.new('test.mrc')
42
+ #
43
+ # @example Get a permissive binary MARC reader
44
+ # reader = MARC4J4R::Reader.new('test.mrc', :permissivemarc)
45
+ #
46
+ # @example Get a reader for an xml file
47
+ # reader = MARC4J4R::Reader.new('test.xml', :marcxml)
48
+ #
49
+ # @example Get a reader based on an existing IO object
50
+ # require 'open-uri'
51
+ # infile = open('http://my.machine.com/test.mrc')
52
+ # reader = MARC4J4R::Reader.new(infile)
53
+
54
+ attr_reader :handle
55
+ def self.new(input, type = :strictmarc)
56
+ @handle = IOConvert.byteinstream(input)
57
+ case type
58
+ when :strictmarc then
59
+ return Java::org.marc4j.MarcStreamReader.new(@handle)
60
+ when :permissivemarc then
61
+ return Java::org.marc4j.MarcPermissiveStreamReader.new(@handle, true, true)
62
+ when :marcxml then
63
+ return Java::org.marc4j.MarcXmlReader.new(@handle)
64
+ when :alephsequential then
65
+ return MARC4J4R::AlephSequentialReader.new(@handle)
66
+ else
67
+ raise ArgumentError, "Reader type #{type} illegal: must be :strictmarc, :permissivemarc, :marcxml, or :alephsequential"
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,214 @@
1
+ module MARC4J4R
2
+ Record = Java::org.marc4j.marc.impl::RecordImpl
3
+
4
+ class Record
5
+ include Enumerable
6
+
7
+ alias_method :<<, :addVariableField
8
+ alias_method :append, :addVariableField
9
+ alias_method :fields, :getVariableFields
10
+
11
+ # Export as a MARC-Hash, as described at
12
+ # http://robotlibrarian.billdueber.com/marc-hash-the-saga-continues-now-with-even-less-structure/
13
+ # @return A marc-hash representation of the record, suitable for calling .to_json on or whatever
14
+
15
+ # Show equality
16
+
17
+ def == other
18
+ return false unless (self.leader == other.leader)
19
+ self.zip(other) do |so|
20
+ return false unless so[0] == so[1]
21
+ end
22
+ other.zip(self) do |so|
23
+ return false unless so[0] == so[1]
24
+ end
25
+ return true
26
+ end
27
+
28
+
29
+ # Create a local hash by tag number; makes some stuff faster
30
+ # Called automatically if you use reader.each
31
+
32
+ def hashify
33
+ return if @hashedtags # don't do it more than once
34
+ @hashedtags = {}
35
+ self.getVariableFields.each do |f|
36
+ @hashedtags[f.tag] ||= []
37
+ @hashedtags[f.tag].push f
38
+ end
39
+ end
40
+
41
+ # Create a nice string of the record
42
+ def to_s
43
+ arr = ['LEADER ' + self.leader]
44
+ self.each do |f|
45
+ arr.push f.to_s
46
+ end
47
+ return arr.join("\n")
48
+ end
49
+
50
+ # Get the leader as a string (marc4j would otherwise return Leader object)
51
+ def leader
52
+ self.get_leader.toString
53
+ end
54
+
55
+ # Set the leader
56
+ def leader= str
57
+ begin
58
+ self.set_leader Java::org.marc4j.marc.impl.LeaderImpl.new(str)
59
+ rescue java.lang.StringIndexOutOfBoundsException => e
60
+ throw RuntimeError.new("'#{str}' not a legal leader: #{e.message}")
61
+ end
62
+ end
63
+
64
+ # Cycle through the fields in the order the appear in the record
65
+ def each
66
+ self.getVariableFields.each do |f|
67
+ yield f
68
+ end
69
+ end
70
+
71
+ # Get the first field associated with a tag
72
+ # @param [String] tag The tag
73
+ # @return [Field] The first matching field, or nil if none. Note that
74
+ # to mirror ruby-marc, this returns a single field
75
+
76
+ def [] tag
77
+ if defined? @hashedtags
78
+ if @hashedtags[tag]
79
+ return @hashedtags[tag][0]
80
+ else
81
+ return nil
82
+ end
83
+ else
84
+ return self.getVariableField(tag)
85
+ end
86
+ end
87
+
88
+
89
+ # Get a (possibly empty) list of fields with the given tag(s)
90
+ #
91
+ # @param [String, Array<String>] tags A string (or Array of strings) with the tags you're interested in
92
+ # @param [Boolean] originalorder Whether or not results should be presented in the original order within the
93
+ # record or with a two-column sort of (a) Order of the tag in the list of tags sent, (b) order within that tag
94
+ # in the record
95
+ # @return [Array<Field>] Either an empty list or a list of one or more matched fields will be returned.
96
+ #
97
+ # originalorder == false will use an internal hash and be faster in many cases (see #hashify)
98
+ #
99
+ # @example originalorder == false
100
+ # # Given a record that looks like
101
+ # # 010 $a 68027371
102
+ # # 035 $a (RLIN)MIUG0001728-B
103
+ # # 035 $a (CaOTULAS)159818044
104
+ # # 035 $a (OCoLC)ocm00001728
105
+ #
106
+ # r.find_by_tag(['035', '010']).each {|f| puts f.to_s}
107
+ # # 035 $a (RLIN)MIUG0001728-B
108
+ # # 035 $a (CaOTULAS)159818044
109
+ # # 035 $a (OCoLC)ocm00001728
110
+ # # 010 $a 68027371
111
+ #
112
+ # # The results are ordered first by tag as passed in, then by original order within the tag
113
+ #
114
+ # @example Just get all fields for a single tag
115
+ # ohThirtyFives = r.find_by_tag('035')
116
+ #
117
+ # @example Get a bunch of standard identifiers
118
+ # standardIDs = r.find_by_tag(['022', '020', '010'])
119
+ #
120
+ # @example originalorder == true
121
+ # r.find_by_tag(['035', '010'], true).each {|f| puts f.to_s}
122
+ # # 010 $a 68027371
123
+ # # 035 $a (RLIN)MIUG0001728-B
124
+ # # 035 $a (CaOTULAS)159818044
125
+ # # 035 $a (OCoLC)ocm00001728
126
+
127
+ def find_by_tag(tags, originalorder = false)
128
+ self.hashify unless @hashedtags and !originalorder
129
+ if !tags.is_a? Array
130
+ return @hashedtags[tags] || []
131
+ end
132
+ if originalorder
133
+ return self.find_all {|f| tags.include? f.tag}
134
+ else
135
+ # puts "Tags is #{tags}: got #{@hashedtags.values_at(*tags)}"
136
+ return @hashedtags.values_at(*tags).flatten.compact
137
+ end
138
+ end
139
+
140
+
141
+
142
+ # Return the record as valid MARC-XML
143
+ # @return String A MARC-XML representation of the record, including the XML header
144
+ def to_xml
145
+ begin
146
+ xml = java.io.StringWriter.new
147
+ res = javax.xml.transform.stream.StreamResult.new(xml)
148
+ writer = org.marc4j.MarcXmlWriter.new(res)
149
+ writer.write(self)
150
+ writer.writeEndDocument
151
+ return xml.toString
152
+ rescue
153
+ "Woops! to_xml failed for record #{self['001'].data}: #{$!}"
154
+ end
155
+ end
156
+
157
+ def to_marc
158
+ begin
159
+ s = Java::java.io.ByteArrayOutputStream.new
160
+ writer = org.marc4j.MarcStreamWriter.new(s)
161
+ writer.write(self)
162
+ @marcbinary = s.to_string
163
+ return @marcbinary
164
+ rescue
165
+ # "Woops! to_marc failed for record #{self['001'].data}: #{$!}"
166
+ "Whoops! Failed: #{$!}"
167
+ end
168
+ end
169
+ end
170
+
171
+
172
+ def to_marchash
173
+ h = {}
174
+ h['type'] = 'marc-hash'
175
+ h['version'] = [1,0]
176
+ h['leader'] = self.leader
177
+
178
+ fields = []
179
+
180
+ self.getVariableFields.each do |f|
181
+ if f.controlField?
182
+ fields << [f.tag, f.value]
183
+ else
184
+ farray = [f.tag, f.indicator1 || ' ', f.indicator2 || ' ']
185
+ subs = []
186
+ f.each do |subfield|
187
+ subs << [subfield.code, subfield.value]
188
+ end
189
+ farray.push subs
190
+ fields << farray
191
+ end
192
+ end
193
+ h['fields'] = fields
194
+ return h
195
+ end
196
+
197
+ # Give a marc record in a string, turn it into an object
198
+ # @param String str The record as a MARC binary string
199
+ # @return MARC4J4R::Record The first record encoded in the string
200
+ def self.from_string str
201
+ return MARC4J4R::Reader.new(StringIO.new(str)).first
202
+ end
203
+
204
+
205
+ # Give a marc-xml record in a string, turn it into an object
206
+ # @param String str The record as a MARC-XML string
207
+ # @return MARC4J4R::Record The first record encoded in the string
208
+ def self.from_xml_string str
209
+ return MARC4J4R::Reader.new(StringIO.new(str), :marcxml).first
210
+ end
211
+
212
+
213
+ end
214
+
@@ -0,0 +1,29 @@
1
+ module MARC4J4R
2
+ # Add some sugar to the MarcWriter interface
3
+ #
4
+ # Adjust the interface so that a #new call to any implementations that
5
+ # implement it can take a java.io.InputStream, ruby IO object, or String
6
+ # (that will be interpreted as a filename) without complaining.
7
+ #
8
+ # The mechanism -- running module_eval on a string-representation of the
9
+ # new method in each of the hard-coded implementations -- is ugly
10
+ # and deeply unsettling.
11
+ #
12
+ # @author Bill Dueber
13
+ #
14
+
15
+ class Writer
16
+
17
+ # A simple factory to return the correct type of writer
18
+ def self.new output, type = :strictmarc
19
+ @handle = IOConvert.byteoutstream(output)
20
+ if type == :strictmarc
21
+ return Java::org.marc4j.MarcStreamWriter.new(@handle)
22
+ elsif type == :marcxml
23
+ return Java::org.marc4j.MarcStreamWriter.new(@handle)
24
+ else
25
+ raise ArgumentError.new("#{type} must be :strictmarc or :marcxml")
26
+ end
27
+ end
28
+ end
29
+ end