do not parse private tags into MARC fields

This commit is contained in:
Jörg Prante 2022-11-04 18:18:57 +01:00
parent a66fae1014
commit 9950003ea7
3 changed files with 58 additions and 31 deletions

View file

@ -1,5 +1,5 @@
group = org.xbib group = org.xbib
name = marc name = marc
version = 2.9.3 version = 2.9.4
org.gradle.warning.mode = ALL org.gradle.warning.mode = ALL

View file

@ -42,6 +42,10 @@ public class MarcField implements Comparable<MarcField> {
public static final MarcFieldValidator DEFAULT_VALIDATOR = new StrictMarcFieldValidator(); 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 = "$"; public static final String DELIMITER = "$";
private final Builder builder; private final Builder builder;
@ -605,7 +609,7 @@ public class MarcField implements Comparable<MarcField> {
} }
case 2: { case 2: {
tag(key.get(0)); tag(key.get(0));
String indicator = key.get(1).replace('_', ' '); String indicator = key.get(1);
if (indicator.isEmpty()) { if (indicator.isEmpty()) {
indicator(" "); indicator(" ");
} else { } else {
@ -623,13 +627,13 @@ public class MarcField implements Comparable<MarcField> {
} }
case 3: { case 3: {
tag(key.get(0)); tag(key.get(0));
String indicator = key.get(1).replace('_', ' '); String indicator = key.get(1);
if (indicator.isEmpty()) { if (indicator.isEmpty()) {
indicator(" "); indicator(" ");
} else { } else {
indicator(indicator); indicator(indicator);
} }
String subfieldIds = key.get(2).replace('_', ' '); String subfieldIds = key.get(2);
if (subfieldIds.isEmpty()) { if (subfieldIds.isEmpty()) {
subfieldIds = " "; subfieldIds = " ";
} }

View file

@ -22,6 +22,8 @@ import static org.xbib.marc.json.MarcJsonWriter.TYPE_TAG;
import org.xbib.marc.label.RecordLabel; import org.xbib.marc.label.RecordLabel;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -30,8 +32,6 @@ import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** /**
@ -41,7 +41,7 @@ public class MarcRecord implements Map<String, Object> {
private static final MarcRecord EMPTY_RECORD = Marc.builder().buildRecord(); private static final MarcRecord EMPTY_RECORD = Marc.builder().buildRecord();
private final Map<String, Object> delegate; private Map<String, Object> delegate;
private String format; private String format;
@ -78,7 +78,7 @@ public class MarcRecord implements Map<String, Object> {
throw new NullPointerException("record label must not be null"); throw new NullPointerException("record label must not be null");
} }
this.marcFields = marcFields; 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<String, Object> {
} }
public static MarcRecord from(Map<String, Object> map) { public static MarcRecord from(Map<String, Object> 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<String, Object> map, Collection<String> privateTags) {
return from(map, MarcField.DEFAULT_VALIDATOR,
FORMAT_TAG, TYPE_TAG, LEADER_TAG, RecordLabel.EMPTY, privateTags);
} }
public static MarcRecord from(Map<String, Object> map, public static MarcRecord from(Map<String, Object> map,
MarcFieldValidator validator,
String formatTag, String formatTag,
String typeTag, String typeTag,
String leaderTag, String leaderTag,
RecordLabel recordLabel) { RecordLabel recordLabel,
Collection<String> privateTags) {
MarcRecord marcRecord = new MarcRecord(map); MarcRecord marcRecord = new MarcRecord(map);
marcRecord.parseMap(map, "", new LinkedList<>(), (key, value) -> Set<String> forbidden = new HashSet<>(privateTags);
marcRecord.marcFields.add(MarcField.builder().key(key, value).build())); 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)) { if (map.containsKey(formatTag)) {
marcRecord.format = map.get(formatTag).toString(); marcRecord.format = map.get(formatTag).toString();
} }
@ -349,6 +364,10 @@ public class MarcRecord implements Map<String, Object> {
return array[0]; return array[0];
} }
public void rebuildMap() {
this.delegate = createMapFromMarcFields(true);
}
@Override @Override
public int size() { public int size() {
return delegate.size(); return delegate.size();
@ -426,7 +445,7 @@ public class MarcRecord implements Map<String, Object> {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private Map<String, Object> createMap(boolean stable) { private Map<String, Object> createMapFromMarcFields(boolean stable) {
Map<String, Object> map = stable ? new TreeMap<>() : new LinkedHashMap<>(); Map<String, Object> map = stable ? new TreeMap<>() : new LinkedHashMap<>();
map.put(FORMAT_TAG, format); map.put(FORMAT_TAG, format);
map.put(TYPE_TAG, type); map.put(TYPE_TAG, type);
@ -482,33 +501,37 @@ public class MarcRecord implements Map<String, Object> {
private void parseMap(Map<String, Object> source, private void parseMap(Map<String, Object> source,
String prefix, String prefix,
LinkedList<String> key, LinkedList<String> key,
Set<String> forbidden,
BiConsumer<List<String>, Object> consumer) { BiConsumer<List<String>, Object> consumer) {
if (!prefix.isEmpty()) { if (!prefix.isEmpty()) {
key.addLast(prefix); key.addLast(prefix);
} }
LinkedList<Map.Entry<String, Object>> list = new LinkedList<>(); LinkedList<Map.Entry<String, Object>> list = new LinkedList<>();
source.forEach((k, v) -> { source.forEach((k, v) -> {
if (v instanceof Map) { // skip our forbidden keys
parseMap((Map<String, Object>) v, k, key, consumer); if (!forbidden.contains(k)) {
} else if (v instanceof Collection) { if (v instanceof Map) {
Collection<Object> collection = (Collection<Object>) v; parseMap((Map<String, Object>) v, k, key, forbidden, consumer);
// join into a single map if we have a collection of plain maps } else if (v instanceof Collection) {
Map<String, Object> map = new LinkedHashMap<>(); Collection<Object> collection = (Collection<Object>) v;
for (Object object : collection) { // join into a single map if we have a collection of plain maps
if (object instanceof Map) { Map<String, Object> map = new LinkedHashMap<>();
Map<String, Object> m = (Map<String, Object>) object; for (Object object : collection) {
if (!join(map, m)) { if (object instanceof Map) {
parseMap(m, k, key, consumer); Map<String, Object> m = (Map<String, Object>) 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()) { if (!list.isEmpty()) {