marc4j4r 0.1.6 → 0.2.2

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