1 // $Id: MarcStreamWriter.java,v 1.4 2006/08/04 12:24:05 bpeters Exp $
\r
3 * Copyright (C) 2004 Bas Peters
\r
5 * This file is part of MARC4J
\r
7 * MARC4J is free software; you can redistribute it and/or
\r
8 * modify it under the terms of the GNU Lesser General Public
\r
9 * License as published by the Free Software Foundation; either
\r
10 * version 2.1 of the License, or (at your option) any later version.
\r
12 * MARC4J is distributed in the hope that it will be useful,
\r
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
\r
15 * Lesser General Public License for more details.
\r
17 * You should have received a copy of the GNU Lesser General Public
\r
18 * License along with MARC4J; if not, write to the Free Software
\r
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
23 import java.io.ByteArrayOutputStream;
\r
24 import java.io.IOException;
\r
25 import java.io.OutputStream;
\r
26 import java.text.DecimalFormat;
\r
27 import java.util.Iterator;
\r
28 import java.util.List;
\r
30 import org.marc4j.converter.CharConverter;
\r
31 import org.marc4j.marc.ControlField;
\r
32 import org.marc4j.marc.DataField;
\r
33 import org.marc4j.marc.Leader;
\r
34 import org.marc4j.marc.Record;
\r
35 import org.marc4j.marc.Subfield;
\r
38 * Class for writing MARC record objects in ISO 2709 format.
\r
41 * The following example reads a file with MARCXML records and outputs the
\r
42 * record set in ISO 2709 format:
\r
46 * InputStream input = new FileInputStream("marcxml.xml");
\r
47 * MarcXmlReader reader = new MarcXmlReader(input);
\r
48 * MarcWriter writer = new MarcStreamWriter(System.out);
\r
49 * while (reader.hasNext()) {
\r
50 * Record record = reader.next();
\r
51 * writer.write(record);
\r
57 * To convert characters like for example from UCS/Unicode to MARC-8 register
\r
58 * a {@link org.marc4j.converter.CharConverter} implementation:
\r
62 * InputStream input = new FileInputStream("marcxml.xml");
\r
63 * MarcXmlReader reader = new MarcXmlReader(input);
\r
64 * MarcWriter writer = new MarcStreamWriter(System.out);
\r
65 * writer.setConverter(new UnicodeToAnsel());
\r
66 * while (reader.hasNext()) {
\r
67 * Record record = reader.next();
\r
68 * writer.write(record);
\r
73 * @author Bas Peters
\r
74 * @version $Revision: 1.4 $
\r
76 public class MarcStreamWriter implements MarcWriter {
\r
78 private OutputStream out = null;
\r
80 private String encoding = "ISO8859_1";
\r
82 private CharConverter converter = null;
\r
84 private static DecimalFormat format4 = new DecimalFormat("0000");
\r
86 private static DecimalFormat format5 = new DecimalFormat("00000");
\r
89 * Constructs an instance and creates a <code>Writer</code> object with
\r
90 * the specified output stream.
\r
92 public MarcStreamWriter(OutputStream out) {
\r
97 * Constructs an instance and creates a <code>Writer</code> object with
\r
98 * the specified output stream and character encoding.
\r
100 public MarcStreamWriter(OutputStream out, String encoding) {
\r
101 this.encoding = encoding;
\r
106 * Returns the character converter.
\r
108 * @return CharConverter the character converter
\r
110 public CharConverter getConverter() {
\r
115 * Sets the character converter.
\r
118 * the character converter
\r
120 public void setConverter(CharConverter converter) {
\r
121 this.converter = converter;
\r
125 * Writes a <code>Record</code> object to the writer.
\r
128 * the <code>Record</code> object
\r
130 public void write(Record record) {
\r
134 ByteArrayOutputStream data = new ByteArrayOutputStream();
\r
135 ByteArrayOutputStream dir = new ByteArrayOutputStream();
\r
138 List<ControlField> fields = record.getControlFields();
\r
139 Iterator<ControlField> i = fields.iterator();
\r
140 while (i.hasNext()) {
\r
141 ControlField cf = (ControlField) i.next();
\r
143 data.write(getDataElement(cf.getData()));
\r
144 data.write(Constants.FT);
\r
145 dir.write(getEntry(cf.getTag(), data.size() - previous,
\r
147 previous = data.size();
\r
151 List<DataField> dataFields = record.getDataFields();
\r
152 Iterator<DataField> di = dataFields.iterator();
\r
153 while (di.hasNext()) {
\r
154 DataField df = di.next();
\r
155 data.write(df.getIndicator1());
\r
156 data.write(df.getIndicator2());
\r
157 List<Subfield> subfields = df.getSubfields();
\r
158 Iterator<Subfield> si = subfields.iterator();
\r
159 while (si.hasNext()) {
\r
160 Subfield sf = si.next();
\r
161 data.write(Constants.US);
\r
162 data.write(sf.getCode());
\r
163 data.write(getDataElement(sf.getData()));
\r
165 data.write(Constants.FT);
\r
166 dir.write(getEntry(df.getTag(), data.size() - previous,
\r
168 previous = data.size();
\r
170 dir.write(Constants.FT);
\r
172 // base address of data and logical record length
\r
173 Leader ldr = record.getLeader();
\r
175 ldr.setBaseAddressOfData(24 + dir.size());
\r
176 ldr.setRecordLength(ldr.getBaseAddressOfData() + data.size() + 1);
\r
178 // write record to output stream
\r
182 out.write(dir.toByteArray());
\r
183 out.write(data.toByteArray());
\r
184 out.write(Constants.RT);
\r
186 } catch (IOException e) {
\r
187 throw new MarcException("IO Error occured while writing record", e);
\r
191 private void write(Leader ldr) throws IOException {
\r
192 out.write(format5.format(ldr.getRecordLength()).getBytes(encoding));
\r
193 out.write(ldr.getRecordStatus());
\r
194 out.write(ldr.getTypeOfRecord());
\r
195 out.write(new String(ldr.getImplDefined1()).getBytes(encoding));
\r
196 out.write(ldr.getCharCodingScheme());
\r
197 out.write(Integer.toString(ldr.getIndicatorCount()).getBytes(encoding));
\r
198 out.write(Integer.toString(ldr.getSubfieldCodeLength()).getBytes(
\r
201 .write(format5.format(ldr.getBaseAddressOfData()).getBytes(
\r
203 out.write(new String(ldr.getImplDefined2()).getBytes(encoding));
\r
204 out.write(new String(ldr.getEntryMap()).getBytes(encoding));
\r
208 * Closes the writer.
\r
210 public void close() {
\r
213 } catch (IOException e) {
\r
214 throw new MarcException("IO Error occured on close", e);
\r
218 private byte[] getDataElement(String data) throws IOException {
\r
219 if (converter != null)
\r
220 return converter.convert(data).getBytes(encoding);
\r
221 return data.getBytes(encoding);
\r
224 private byte[] getEntry(String tag, int length, int start)
\r
225 throws IOException {
\r
226 return (tag + format4.format(length) + format5.format(start))
\r
227 .getBytes(encoding);
\r