Java tutorial
package de.gbv.ole; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.text.Normalizer; import java.util.HashMap; import java.util.Map; import java.util.ResourceBundle; import java.util.SortedMap; import java.util.TreeMap; import javax.xml.transform.OutputKeys; import javax.xml.transform.Result; import javax.xml.transform.TransformerFactory; import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TransformerHandler; import javax.xml.transform.stream.StreamResult; import org.apache.commons.lang3.StringUtils; import org.marc4j.Constants; import org.marc4j.MarcException; import org.marc4j.MarcStreamReader; import org.marc4j.MarcWriter; import org.marc4j.converter.CharConverter; import org.marc4j.marc.ControlField; import org.marc4j.marc.DataField; import org.marc4j.marc.MarcFactory; import org.marc4j.marc.Record; import org.marc4j.marc.Subfield; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; /** * Liest eine MARC21-Datei ein, erzeugt drei Dateien fr * den Import per LOAD DATA INFILE in die OLE-Tabellen * ole_ds_bib_t, ole_ds_bib_t und ole_ds_item_t. * This file contains parts of * org.marc4j/MarcXmlWriter.java which is * Copyright (C) 2004 Bas Peters * * This file is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This file is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with MARC4J; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ public class Marc21ToOleBulk implements MarcWriter { /** Factory to create MARC data structures */ protected static final MarcFactory marcFactory = MarcFactory.newInstance(); /** Suffix .mrc der MARC21-Datei. */ private static final String MRCSUFFIX = ".mrc"; /** XML-Tagname. */ protected static final String COLLECTION = "collection"; /** XML-Tagname. */ protected static final String RECORD = "record"; /** XML-Tagname. */ protected static final String LEADER = "leader"; /** XML-Tagname. */ protected static final String CONTROL_FIELD = "controlfield"; /** XML-Tagname. */ protected static final String DATA_FIELD = "datafield"; /** XML-Tagname. */ protected static final String SUBFIELD = "subfield"; /** Ist die Location der Key-Wert, ist sie in den Value-Wert zu ndern. */ protected static final Map<String, String> convertLocation = new HashMap<String, String>(); static { convertLocation.put("ALT", "UB/BIBO"); convertLocation.put("Alt", "UB/BIBO"); convertLocation.put("AMI", "UB/BIBO"); convertLocation.put("Arbeitsbibliothek Holthusen", "UB/BIBO"); convertLocation.put("AZP", "UB/BIBO"); convertLocation.put("HA", "UB/BIBO"); convertLocation.put("HB", "UB/BIBO"); convertLocation.put("HI/UB/LS", "UB/BIBO"); convertLocation.put("LEIHSTELLE", "UB/BIBO"); convertLocation.put("Leihstelle", "UB/BIBO"); convertLocation.put("Leselounge", "UB/BIBO"); convertLocation.put("LS-NUTZUNG", "UB/BIBO"); convertLocation.put("!MAGAZIN", "UB/MAG"); convertLocation.put("HI/UB/MG", "UB/MAG"); convertLocation.put("MAGAZIN", "UB/MAG"); convertLocation.put("Magazin", "UB/MAG"); convertLocation.put("Verlust", "UB/MAG"); convertLocation.put("ZSS-Dublettenlager", "UB/MAG"); convertLocation.put("ZSS-MAGAZIN", "UB/MAG"); convertLocation.put("ZSS-Magazin", "UB/MAG"); convertLocation.put("MEDIENARCHIV", "UB/BIBO"); convertLocation.put("Medienarchiv", "UB/BIBO"); convertLocation.put("MEDIOTHEK", "UB/BIBO"); convertLocation.put("Mediothek", "UB/BIBO"); convertLocation.put("MIKROFORM", "UB/BIBO"); convertLocation.put("MiKROFORM", "UB/BIBO"); convertLocation.put("ATLANTENSCHRANK", "UB/BIBO"); convertLocation.put("Ausgeschieden", "UB/BIBO"); convertLocation.put("HI", "UB/BIBO"); convertLocation.put("Makuliert", "UB/BIBO"); convertLocation.put("PRF", "UB/BIBO"); convertLocation.put("PRZ", "UB/BIBO"); convertLocation.put("RARA", "UB/BIBO"); convertLocation.put("Rara", "UB/BIBO"); convertLocation.put("STA", "UB/BIBO"); convertLocation.put("", "UB/BIBO"); } /** * Type of an item * <li>{@link #BUA}</li> * <li>{@link #BUP}</li> * <li>{@link #BUZ}</li> * <li>{@link #AVA}</li> * <li>{@link #AVP}</li> * <li>{@link #AVZ}</li> * <li>{@link #ZSP}</li> * <li>{@link #MKP}</li> */ enum ItemType { /** BUA Buch ausleihbar */ BUA(90), /** BUP Buch prsenz */ BUP(91), /** BUZ Buch nach Zustimmung ausleihbar */ BUZ(92), /** AVA AV ausleihbar */ AVA(93), /** AVP AV prsenz */ AVP(94), /** AVZ AV nach Zustimmung ausleihbar */ AVZ(95), /** ZSP Zeitschrift prsenz */ ZSP(96), /** MKP Mikroform prsenz */ MKP(97); private int value; private ItemType(int value) { this.value = value; } } /** True to output only PPNs with 5 before check digit */ private boolean ppn5 = false; /** XML transformer handler. */ private TransformerHandler handler = null; /** bib output stream. */ private Writer bibWriter = null; /** holdings output stream. */ private Writer holdingsWriter = null; /** item output stream. */ private Writer itemWriter = null; /** * Print usage to System.err and exit the program. */ private static void usageExit() { ResourceBundle messages = ResourceBundle.getBundle("application"); System.err.println(messages.getString("usage")); System.exit(1); } /** * Setup of output. * @param bib bib destination * @param holdings holdings destination * @param item item destination * @param ppn5 true to output only PPNs with 5 before check digit */ public Marc21ToOleBulk(final Writer bibWriter, final Writer holdingsWriter, final Writer itemWriter, final boolean ppn5) { this.bibWriter = bibWriter; this.holdingsWriter = holdingsWriter; this.itemWriter = itemWriter; setHandler(new StreamResult(bibWriter)); this.ppn5 = ppn5; } /** * Set the <code>Result</code> associated with this * <code>TransformerHandler</code> to be used for the transformation. * * @param result the Result to be used for the transformation */ protected final void setHandler(final Result result) { try { TransformerFactory factory = TransformerFactory.newInstance(); if (!factory.getFeature(SAXTransformerFactory.FEATURE)) { throw new UnsupportedOperationException("SAXTransformerFactory is not supported"); } SAXTransformerFactory saxFactory = (SAXTransformerFactory) factory; handler = saxFactory.newTransformerHandler(); handler.getTransformer().setOutputProperty(OutputKeys.METHOD, "xml"); handler.setResult(result); } catch (Exception e) { throw new MarcException(e.getMessage(), e); } } /** * Return the input without the tailing check digit. * * Example: * withoutCheckdigit("123456789X") = "123456789" * withoutCheckdigit("987654321") = "98765432" * * @param numberWithCheckdigit - number including check digit * @return number without check digit */ static final String withoutCheckdigit(final String numberWithCheckdigit) { return StringUtils.left(numberWithCheckdigit, numberWithCheckdigit.length() - 1); } /** * Return the ISBN10 check digit for number. * * isbn10checkdigit( 0) = "0" * isbn10checkdigit( 1) = "9" * isbn10checkdigit(212121212) = "4" * isbn10checkdigit(123456789) = "X" * isbn10checkdigit(999999999) = "9" * * @param number from the range 0 .. 999999999 * @throws IllegalArgumentException if number is off range * @return calculated check digit (0 .. 9 or X) */ static final String isbn10checkdigit(final int number) { if (number < 0 || number > 999999999) { throw new IllegalArgumentException( "number from range 0 .. 999999999 expected, " + "but found " + number); } int n = number; int sum = 0; int factor = 9; while (n != 0) { sum += (n % 10) * factor; factor--; n /= 10; } int checkdigit = sum % 11; if (checkdigit == 10) { return "X"; } return Integer.toString(checkdigit); } /** * Throws a MarcException if the parameter is not a valid isbn10 number * with valid check digit. * * Valid: "00", "19", "27", * "2121212124", * "9999999980", * "9999999999" * * @param isbn10 the number to validate */ static void validateIsbn10(final String isbn10) { if (StringUtils.isEmpty(isbn10)) { throw new MarcException("null or empty number"); } if (StringUtils.isWhitespace(isbn10)) { throw new MarcException("number expected, found only whitespace"); } if (StringUtils.containsWhitespace(isbn10)) { throw new MarcException( "number plus check digit expected, but contains " + "whitespace: '" + isbn10 + "'"); } if (isbn10.length() < 2) { throw new MarcException("number plus check digit expected, " + "but found: " + isbn10); } if (isbn10.length() > 10) { throw new MarcException("maximum length of number plus " + "check digit is 10 (9 + 1 check digit),\n" + "input is " + isbn10.length() + " characters long: " + isbn10); } String checkdigit = StringUtils.right(isbn10, 1); if (!StringUtils.containsOnly(checkdigit, "0123456789xX")) { throw new MarcException("check digit must be 0-9, x or X, " + "but is " + checkdigit); } String number = withoutCheckdigit(isbn10); if (!StringUtils.containsOnly(number, "0123456789")) { throw new MarcException("number before check digit must " + "contain 0-9 only, but is " + checkdigit); } String calculatedCheckdigit = isbn10checkdigit(Integer.parseInt(number)); if (!StringUtils.equalsIgnoreCase(checkdigit, calculatedCheckdigit)) { throw new MarcException("wrong checkdigit " + checkdigit + ", correct check digit is " + calculatedCheckdigit + ": " + isbn10); } } /** * Write the Record object to the output files. * * @param record - the <code>Record</code> object */ public final void write(final Record record) { /* get control field 001 */ String ppn = record.getControlNumber(); if (ppn5) { // Nur Daten mit 5 vor der PPN-Prfziffer ausgeben; // das reduziert den Datenumfang auf ca. 10 % if (!StringUtils.substring(ppn, -2, -1).equals("5")) { return; } } try { validateIsbn10(ppn); bibWriter.write(withoutCheckdigit(ppn)); bibWriter.write("\t"); toXml(ppn, record); bibWriter.write("\n"); } catch (Exception e) { throw new MarcException("Control field 001 (PPN): " + ppn, e); } } /** * Start the element using <code>handler</code>. * * @param name used for localName and qName * @param atts the attributes to attach to the element * @throws SAXException bei XML-Fehler */ private void startElement(final String name, final Attributes atts) throws SAXException { handler.startElement(Constants.MARCXML_NS_URI, name, name, atts); } /** * Start the element without attributes using <code>handler</code>. * * @param name used for localName and qName * @throws SAXException bei XML-Fehler */ private void startElement(final String name) throws SAXException { AttributesImpl atts = new AttributesImpl(); startElement(name, atts); } /** * End the element using <code>handler</code>. * * @param name used for localName and qName * @throws SAXException bei XML-Fehler */ private void endElement(final String name) throws SAXException { handler.endElement(Constants.MARCXML_NS_URI, name, name); } /** * Add an CDATA attribute. * * @param atts where to add * @param name used for localName and qName * @param value attribute value */ private void add(final AttributesImpl atts, final String name, final String value) { atts.addAttribute("", name, name, "CDATA", value); } /** * Add an CDATA attribute. * * @param atts where to add * @param name used for localName and qName * @param value attribute value */ private void add(final AttributesImpl atts, final String name, final char value) { atts.addAttribute("", name, name, "CDATA", String.valueOf(value)); } /** * Write data to bib output. * * Does Unicode NFC normalization. * * Masks these four characters: \n \r \t \\ * This masking is needed for LOAD DATA INFILE. * * @param data data to write * @throws SAXException on write error */ private void write(final String data) throws SAXException { String normalized = Normalizer.normalize(data, Normalizer.Form.NFC); char[] charArray = StringUtils.replaceEach(normalized, new String[] { "\n", "\r", "\t", "\\", }, new String[] { "\\\n", "\\\r", "\\\t", "\\\\", }).toCharArray(); handler.characters(charArray, 0, charArray.length); } /** * Print the content of field as a multiline String. * @param field content to print * @return multiline String */ final static String print(final DataField field) { StringBuffer s = new StringBuffer(); s.append(field.getTag()); s.append(' ').append(field.getIndicator1()); s.append(' ').append(field.getIndicator2()); s.append('\n'); for (Subfield subfield : field.getSubfields()) { s.append(subfield.getCode()).append(' ').append(subfield.getData()).append('\n'); } return s.toString(); } /** * Schreibt die Exemplare sortiert nach Exemplarnummer. * @param ppn PPN der Exemplare. * @param record Record, zu dem das Exemplar gehrt * @param exemplare Zu konvertierende und schreibende Exemplare. * @throws IOException bei Ausgabefehler */ void write(String ppn, Record record, Map<String, Exemplar> exemplare) throws IOException { SortedMap<String, Exemplar> sort = new TreeMap<String, Exemplar>(exemplare); for (Map.Entry<String, Exemplar> e : sort.entrySet()) { String exemplarnummer = e.getKey(); Exemplar exemplar = e.getValue(); fetchItemType(record, exemplar); write(ppn, exemplarnummer, exemplar); } } void write(String ppn, String exemplarnummer, Exemplar exemplar) throws IOException { String ppnCut = withoutCheckdigit(ppn); String epnCut = withoutCheckdigit(exemplar.epn); // holdings_id=epnCut, bib_id=ppnCut holdingsWriter.write(epnCut + "\t" // holdings_id + ppnCut + "\t" // bib_id + exemplar.location + "\t" + exemplar.callnumber + "\t" + exemplar.shelvingOrder + "\n"); // item_id=epnCut, holdings_id=epnCut itemWriter.write(epnCut + "\t" // item_id + epnCut + "\t" // holdings_id + exemplar.barcode + "\t" + exemplar.itemType + "\n"); // item_type_id (ole_cat_itm_typ_t) } /** * Writes a Record object to the result. * * @param ppn PPN of the record * @param record - * the <code>Record</code> object * @throws SAXException */ protected final void toXml(final String ppn, final Record record) throws SAXException, IOException { if (!marcFactory.validateRecord(record)) { throw new MarcException("Marc record didn't validate"); } startElement(COLLECTION); startElement(RECORD); startElement(LEADER); write(record.getLeader().toString()); endElement(LEADER); for (ControlField field : record.getControlFields()) { AttributesImpl atts = new AttributesImpl(); add(atts, "tag", field.getTag()); startElement(CONTROL_FIELD, atts); write(field.getData()); endElement(CONTROL_FIELD); } Map<String, Exemplar> exemplare = new HashMap<String, Exemplar>(); for (DataField field : record.getDataFields()) { if (field == null) { throw new MarcException("DataField is null"); } try { { AttributesImpl atts = new AttributesImpl(); add(atts, "tag", field.getTag()); add(atts, "ind1", field.getIndicator1()); add(atts, "ind2", field.getIndicator2()); startElement(DATA_FIELD, atts); } for (Subfield subfield : field.getSubfields()) { AttributesImpl atts = new AttributesImpl(); add(atts, "code", subfield.getCode()); startElement(SUBFIELD, atts); write(subfield.getData()); endElement(SUBFIELD); } endElement(DATA_FIELD); exemplar(field, exemplare); } catch (Exception e) { throw new MarcException("Marc data field: " + print(field), e); } } endElement(RECORD); endElement(COLLECTION); write(ppn, record, exemplare); } /** * Returns true iff c is a digit from 0 .. 9. * @param c char to test * @return true if digit, false otherwise */ final static boolean isDigit(final char c) { return '0' <= c && c <= '9'; } /** * Liest Exemplarinformationen aus dem DataField, * schreibt sie nach exemplare, getrennt nach * Exemplarnummer. * @param field Datenquelle * @param exemplare Datenziel */ static void exemplar(final DataField field, Map<String, Exemplar> exemplare) { String tag = field.getTag(); if (!StringUtils.equals(tag, "980") && !StringUtils.equals(tag, "984")) { return; } Subfield ilnSubfield = field.getSubfield('2'); if (ilnSubfield == null) { throw new MarcException("ILN expected, but subfield 2 is missing"); } String iln = ilnSubfield.getData(); if (StringUtils.isBlank(iln)) { throw new MarcException("ILN expected, but subfield 2 is empty"); } // wir wollen nur Hildesheimer Daten, ILN 90 if (!"90".equals(iln.trim())) { return; } Subfield exemplarmummerSubfield = field.getSubfield('1'); if (exemplarmummerSubfield == null) { throw new MarcException("Exemplarnummer expected, but subfield 1 is missing"); } String exemplarnummer = exemplarmummerSubfield.getData(); if (StringUtils.isBlank(exemplarnummer)) { throw new MarcException("Exemplarnummer expected, but subfield 1 is empty"); } exemplarnummer = exemplarnummer.trim(); if (exemplarnummer.length() != 2) { throw new MarcException("Exemplarnummer with 2 digits expected, but found " + exemplarnummer); } if (!isDigit(exemplarnummer.charAt(0)) || !isDigit(exemplarnummer.charAt(1))) { throw new MarcException("Exemplarnummer with 2 digits expected, but found " + "a non-digit character: " + exemplarnummer); } Exemplar exemplar = exemplare.get(exemplarnummer); if (exemplar == null) { exemplar = new Exemplar(); exemplare.put(exemplarnummer, exemplar); } if ("980".equals(tag)) { fetchEPN(field, exemplar); fetchCallnumber(field, exemplar); fetchLocation(field, exemplar); fetchAusleihindikator(field, exemplar); } else if ("984".equals(tag)) { fetchBarcode(field, exemplar); } } /** * Holt den Wert aus dem angegebenen Subfeld, macht trim(). * * @param field MARC-Feld, in dem nach dem Subfeld gesucht wird * @param subfieldName Name des gesuchten Subfeldes * @param subfieldDescription Feldbezeichnung fr Fehlermeldungen * @return gesuchter Wert * @throws MarcException wenn Subfeld fehlt oder (bis auf Whitespace) * leer ist. */ final static String requiredSubfield(final DataField field, char subfieldName, String subfieldDescription) { Subfield subfield = field.getSubfield(subfieldName); if (subfield == null) { throw new MarcException(subfieldDescription + " expected, subfield " + subfieldName + " is missing"); } String value = subfield.getData(); if (StringUtils.isBlank(value)) { throw new MarcException(subfieldDescription + " expected, subfield " + subfieldName + " is empty"); } return value.trim(); } /** * Holt den Wert aus dem angegebenen Subfeld, macht trim(), * liefert "" statt null. * @param field MARC-Feld, in dem nach dem Subfeld gesucht wird * @param subfieldName Name des gesuchten Subfeldes * @return gesuchter Wert */ final static String optionalSubfield(final DataField field, char subfieldName) { Subfield subfield = field.getSubfield(subfieldName); if (subfield == null) { return ""; } return StringUtils.defaultString(subfield.getData()).trim(); } /** * Liest aus Subfeld b des MARC-Felds die EPN, schreibt sie in * das Exemplar und validiert sie. * @param field MARC-Feld * @param exemplar das Exemplar * @throws MarcException wenn die EPN ungltig ist */ final static void fetchEPN(final DataField field, Exemplar exemplar) { exemplar.epn = requiredSubfield(field, 'b', "EPN"); validateIsbn10(exemplar.epn); } /** * Liest aus Subfeld a des MARC-Felds den optionalen Barcode und * schreibt ihn das Exemplar. * @param field MARC-Feld, das den Barcode enthalten kann * @param exemplar das Exemplar */ final static void fetchBarcode(final DataField field, Exemplar exemplar) { Subfield barcodeField = field.getSubfield('a'); if (barcodeField == null) { return; } String barcode = barcodeField.getData(); if (StringUtils.isBlank(barcode)) { throw new MarcException("Barcode expected, subfield a is empty"); } exemplar.barcode = barcode.trim(); } /** * Liest aus Subfeld d des MARC-Felds die optionale Callnumber und * schreibt sie und die dazugehrige shelvingOrder in das Exemplar. * @param field MARC-Feld, das die Callnumber enthalten kann * @param exemplar das Exemplar */ final static void fetchCallnumber(final DataField field, Exemplar exemplar) { exemplar.callnumber = optionalSubfield(field, 'd'); exemplar.shelvingOrder = CallNumber.getShelvingOrder(exemplar.callnumber); } /** * Liest aus Subfeld f des MARC-Felds die optionale Location und * schreibt sie in das Exemplar. * @param field MARC-Feld, das die Location enthalten kann * @param exemplar das Exemplar */ final static void fetchLocation(final DataField field, Exemplar exemplar) { String location = optionalSubfield(field, 'f'); location = StringUtils.defaultString(convertLocation.get(location), location); exemplar.location = location; } /** * Return s if not empty, a single space otherwise. * @param s zu bearbeitender String, darf null sein * @return String, nicht null und nicht leer. */ final static String empty2space(String s) { if (s == null || "".equals(s)) { return " "; } return s; } /** * Liest aus Subfeld e des MARC-Felds den optionale Ausleihindikator * und schreibt ihn in das Exemplar. * @param field MARC-Feld, das den Ausleihindikator enthalten kann * @param exemplar das Exemplar */ final static void fetchAusleihindikator(final DataField field, Exemplar exemplar) { exemplar.ausleihindikator = empty2space(optionalSubfield(field, 'e')); } /** * Return the data of the control field with number tag with whitespace * trimmed. * @param record Where to search for the control field. * @param tag The number of the control field. * @return The data of the control field. * @throws MarcException if the control field does not exist, * is empty or contains only whitespace */ final static String getRequiredControlField(Record record, String tag) { for (ControlField controlField : record.getControlFields()) { if (!tag.equals(controlField.getTag())) { continue; } String data = StringUtils.trimToEmpty(controlField.getData()); if ("".equals(data)) { throw new MarcException("Control field " + tag + " is empty."); } return data; } throw new MarcException("Control field " + tag + " expected " + "but not found."); } /** * Return the data of the control field with number tag with * whitespace trimmed. * @param record Where to search for the control field. * @param tag The number of the control field. * @return The data of the control field, or an empty String if * the field does not exist or contains only whitespace */ final static String getOptionalControlField(Record record, String tag) { for (ControlField controlField : record.getControlFields()) { if (!tag.equals(controlField.getTag())) { continue; } return StringUtils.trimToEmpty(controlField.getData()); } return ""; } /** * Liest aus Leader und Control Fields sowie dem Ausleihindikator * den item type und schreibt ihn in exemplar. * @param record Record, der Leader und Control Fields enthlt * @param exemplar Exemplar mit Ausleihindikator und Ziel fr Item Type. */ final static void fetchItemType(Record record, Exemplar exemplar) { int itemType = getItemType(record, exemplar); exemplar.itemType = Integer.toString(itemType); } /** * Liest aus Leader und Control Fields sowie dem Ausleihindikator * den item type und liefert seine id zurck. * @param record Record, der Leader und Control Fields enthlt * @param exemplar Exemplar mit Ausleihindikator und Ziel fr Item Type. * @return item type id */ final static int getItemType(Record record, Exemplar exemplar) { // Spec siehe http://www.loc.gov/marc/bibliographic/ String leader = record.getLeader().toString(); String typeOfRecord = leader.substring(6, 7); String bibliographicLevel = leader.substring(7, 8); String field007 = getOptionalControlField(record, "007"); String categoryOfMaterial = empty2space(StringUtils.substring(field007, 0, 1)); String materialDesignation = empty2space(StringUtils.substring(field007, 1, 2)); if (typeOfRecord.equals("a") && "mb".contains(bibliographicLevel)) { if ("ubc".contains(exemplar.ausleihindikator)) { return ItemType.BUA.value; } if ("sd".contains(exemplar.ausleihindikator)) { return ItemType.BUZ.value; } if ("ifgaoz".contains(exemplar.ausleihindikator)) { return ItemType.BUP.value; } } // eBook if (typeOfRecord.equals("m") && bibliographicLevel.equals("m") && categoryOfMaterial.equals("c") && materialDesignation.equals("r")) { return ItemType.BUA.value; } // Zeitschrift if (typeOfRecord.equals("a") && bibliographicLevel.equals("s")) { return ItemType.ZSP.value; } // eZeitschrift if (typeOfRecord.equals("m") && bibliographicLevel.equals("s")) { return ItemType.BUA.value; } // Aufsatz if (typeOfRecord.equals("a") && bibliographicLevel.equals("a")) { return ItemType.ZSP.value; } // eAufsatz if (bibliographicLevel.equals("a")) { return ItemType.BUA.value; } // Handschrift if ("dft".contains(typeOfRecord)) { return ItemType.BUP.value; } // Mikroform if (categoryOfMaterial.equals("h")) { return ItemType.MKP.value; } // Datentrger, Karte, Film, Tontrger, Spiel/Objekt if ("ubc".contains(exemplar.ausleihindikator)) { return ItemType.AVA.value; } if ("sd".contains(exemplar.ausleihindikator)) { return ItemType.AVZ.value; } // ifgaoz return ItemType.AVP.value; } @Override public final void setConverter(final org.marc4j.converter.CharConverter aConverter) { throw new UnsupportedOperationException("setConverter(CharConverter) is not implemented"); } @Override public final CharConverter getConverter() { throw new UnsupportedOperationException("getConverter() is not implemented"); } public void close() { // nothing to do } private static Writer utf8Writer(String filename) throws IOException { FileOutputStream stream = new FileOutputStream(filename); return new OutputStreamWriter(stream, "UTF8"); } /** * Convertiert eine MARC21-Datei in eine MarcXML-Bulk-Import-SQL-Datei. * @param args Pfad mit auf .mrc endendem Dateinamen der MARC21-Datei. * @throws IOException Fehler beim Dateilesen oder -schreiben */ public static void main(final String[] args) throws IOException { if (args.length < 1 || args.length > 2) { usageExit(); } boolean ppn5 = false; if (args.length == 2) { if ("-5".equals(args[0])) { ppn5 = true; } else { usageExit(); } } String infile = args[args.length - 1]; if (!infile.endsWith(MRCSUFFIX)) { System.err.println("Filename ending in .mrc expected, " + "but found filename: " + infile); usageExit(); } InputStream in = new FileInputStream(infile); MarcStreamReader reader = new MarcStreamReader(in); String filename = infile.substring(0, infile.length() - MRCSUFFIX.length()); Writer bib = utf8Writer(filename + "-bib.sql"); Writer holdings = utf8Writer(filename + "-holdings.sql"); Writer item = utf8Writer(filename + "-item.sql"); while (reader.hasNext()) { MarcWriter writer = new Marc21ToOleBulk(bib, holdings, item, ppn5); writer.write(reader.next()); writer.close(); } in.close(); item.close(); holdings.close(); bib.close(); } }