From 9950003ea798d6495aab5771dacd6aebe35d1add Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Prante?= Date: Fri, 4 Nov 2022 18:18:57 +0100 Subject: [PATCH] do not parse private tags into MARC fields --- gradle.properties | 2 +- src/main/java/org/xbib/marc/MarcField.java | 10 ++- src/main/java/org/xbib/marc/MarcRecord.java | 77 +++++++++++++-------- 3 files changed, 58 insertions(+), 31 deletions(-) diff --git a/gradle.properties b/gradle.properties index ccd605d..78971fc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ group = org.xbib name = marc -version = 2.9.3 +version = 2.9.4 org.gradle.warning.mode = ALL diff --git a/src/main/java/org/xbib/marc/MarcField.java b/src/main/java/org/xbib/marc/MarcField.java index 7eca6b0..e108333 100644 --- a/src/main/java/org/xbib/marc/MarcField.java +++ b/src/main/java/org/xbib/marc/MarcField.java @@ -42,6 +42,10 @@ public class MarcField implements Comparable { public static final MarcFieldValidator DEFAULT_VALIDATOR = new StrictMarcFieldValidator(); + public static final MarcFieldValidator STRICT_VALIDATOR = new StrictMarcFieldValidator(); + + public static final MarcFieldValidator PERMISSIVE_VALIDATOR = new PermissiveMarcFieldValidator(); + public static final String DELIMITER = "$"; private final Builder builder; @@ -605,7 +609,7 @@ public class MarcField implements Comparable { } case 2: { tag(key.get(0)); - String indicator = key.get(1).replace('_', ' '); + String indicator = key.get(1); if (indicator.isEmpty()) { indicator(" "); } else { @@ -623,13 +627,13 @@ public class MarcField implements Comparable { } case 3: { tag(key.get(0)); - String indicator = key.get(1).replace('_', ' '); + String indicator = key.get(1); if (indicator.isEmpty()) { indicator(" "); } else { indicator(indicator); } - String subfieldIds = key.get(2).replace('_', ' '); + String subfieldIds = key.get(2); if (subfieldIds.isEmpty()) { subfieldIds = " "; } diff --git a/src/main/java/org/xbib/marc/MarcRecord.java b/src/main/java/org/xbib/marc/MarcRecord.java index 75b4b97..4f4f930 100644 --- a/src/main/java/org/xbib/marc/MarcRecord.java +++ b/src/main/java/org/xbib/marc/MarcRecord.java @@ -22,6 +22,8 @@ import static org.xbib.marc.json.MarcJsonWriter.TYPE_TAG; import org.xbib.marc.label.RecordLabel; import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; @@ -30,8 +32,6 @@ import java.util.Set; import java.util.TreeMap; import java.util.function.BiConsumer; import java.util.function.Predicate; -import java.util.logging.Level; -import java.util.logging.Logger; import java.util.regex.Pattern; /** @@ -41,7 +41,7 @@ public class MarcRecord implements Map { private static final MarcRecord EMPTY_RECORD = Marc.builder().buildRecord(); - private final Map delegate; + private Map delegate; private String format; @@ -78,7 +78,7 @@ public class MarcRecord implements Map { throw new NullPointerException("record label must not be null"); } this.marcFields = marcFields; - this.delegate = lightweight ? Map.of() : createMap(stable); + this.delegate = lightweight ? Map.of() : createMapFromMarcFields(stable); } /** @@ -90,17 +90,32 @@ public class MarcRecord implements Map { } public static MarcRecord from(Map map) { - return from(map, FORMAT_TAG, TYPE_TAG, LEADER_TAG, RecordLabel.EMPTY); + return from(map, MarcField.DEFAULT_VALIDATOR, + FORMAT_TAG, TYPE_TAG, LEADER_TAG, RecordLabel.EMPTY, Collections.emptyList()); + } + + public static MarcRecord from(Map map, Collection privateTags) { + return from(map, MarcField.DEFAULT_VALIDATOR, + FORMAT_TAG, TYPE_TAG, LEADER_TAG, RecordLabel.EMPTY, privateTags); } public static MarcRecord from(Map map, + MarcFieldValidator validator, String formatTag, String typeTag, String leaderTag, - RecordLabel recordLabel) { + RecordLabel recordLabel, + Collection privateTags) { MarcRecord marcRecord = new MarcRecord(map); - marcRecord.parseMap(map, "", new LinkedList<>(), (key, value) -> - marcRecord.marcFields.add(MarcField.builder().key(key, value).build())); + Set forbidden = new HashSet<>(privateTags); + forbidden.add(formatTag); + forbidden.add(typeTag); + forbidden.add(leaderTag); + marcRecord.parseMap(map, "", new LinkedList<>(), forbidden, (key, value) -> + marcRecord.marcFields.add(MarcField.builder() + .setValidator(validator) + .key(key, value) + .build())); if (map.containsKey(formatTag)) { marcRecord.format = map.get(formatTag).toString(); } @@ -349,6 +364,10 @@ public class MarcRecord implements Map { return array[0]; } + public void rebuildMap() { + this.delegate = createMapFromMarcFields(true); + } + @Override public int size() { return delegate.size(); @@ -426,7 +445,7 @@ public class MarcRecord implements Map { } @SuppressWarnings("unchecked") - private Map createMap(boolean stable) { + private Map createMapFromMarcFields(boolean stable) { Map map = stable ? new TreeMap<>() : new LinkedHashMap<>(); map.put(FORMAT_TAG, format); map.put(TYPE_TAG, type); @@ -482,33 +501,37 @@ public class MarcRecord implements Map { private void parseMap(Map source, String prefix, LinkedList key, + Set forbidden, BiConsumer, Object> consumer) { if (!prefix.isEmpty()) { key.addLast(prefix); } LinkedList> list = new LinkedList<>(); source.forEach((k, v) -> { - if (v instanceof Map) { - parseMap((Map) v, k, key, consumer); - } else if (v instanceof Collection) { - Collection collection = (Collection) v; - // join into a single map if we have a collection of plain maps - Map map = new LinkedHashMap<>(); - for (Object object : collection) { - if (object instanceof Map) { - Map m = (Map) object; - if (!join(map, m)) { - parseMap(m, k, key, consumer); + // skip our forbidden keys + if (!forbidden.contains(k)) { + if (v instanceof Map) { + parseMap((Map) v, k, key, forbidden, consumer); + } else if (v instanceof Collection) { + Collection collection = (Collection) v; + // join into a single map if we have a collection of plain maps + Map map = new LinkedHashMap<>(); + for (Object object : collection) { + if (object instanceof Map) { + Map m = (Map) object; + if (!join(map, m)) { + parseMap(m, k, key, forbidden, consumer); + } + } else { + list.add(Map.entry(k, object)); } - } else { - list.add(Map.entry(k, object)); } + if (!map.isEmpty()) { + parseMap(map, k, key, forbidden, consumer); + } + } else { + list.add(Map.entry(k, v)); } - if (!map.isEmpty()) { - parseMap(map, k, key, consumer); - } - } else { - list.add(Map.entry(k, v)); } }); if (!list.isEmpty()) {