fix nested map parsing for MarcField building in MarcRecord
This commit is contained in:
parent
5a644f4e41
commit
399a43d920
4 changed files with 74 additions and 53 deletions
|
@ -1,5 +1,5 @@
|
||||||
group = org.xbib
|
group = org.xbib
|
||||||
name = marc
|
name = marc
|
||||||
version = 2.9.0
|
version = 2.9.1
|
||||||
|
|
||||||
org.gradle.warning.mode = ALL
|
org.gradle.warning.mode = ALL
|
||||||
|
|
|
@ -18,9 +18,10 @@ package org.xbib.marc;
|
||||||
import org.xbib.marc.dialects.mab.MabSubfieldControl;
|
import org.xbib.marc.dialects.mab.MabSubfieldControl;
|
||||||
import org.xbib.marc.label.RecordLabel;
|
import org.xbib.marc.label.RecordLabel;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.Map;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -537,30 +538,25 @@ public class MarcField implements Comparable<MarcField> {
|
||||||
* @param key the key as string
|
* @param key the key as string
|
||||||
* @return this builder
|
* @return this builder
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public Builder key(String key, String separator, Object value) {
|
public Builder key(String key, String separator, Object value) {
|
||||||
String[] s = key.split(separator);
|
String[] s = key.split(separator);
|
||||||
switch (s.length) {
|
switch (s.length) {
|
||||||
case 3: {
|
case 0: {
|
||||||
|
// is that even possible?
|
||||||
|
tag(key);
|
||||||
|
value(value.toString());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1: {
|
||||||
tag(s[0]);
|
tag(s[0]);
|
||||||
String indicator = s[1].replace('_', ' ');
|
if (value instanceof Collection) {
|
||||||
if (indicator.isEmpty()) {
|
Collection<Map.Entry<String, Object>> collection = (Collection<Map.Entry<String, Object>>) value;
|
||||||
indicator(" ");
|
for (Map.Entry<String, Object> entry : collection) {
|
||||||
} else {
|
tag(entry.getKey()).value(entry.getValue().toString());
|
||||||
indicator(indicator);
|
|
||||||
}
|
|
||||||
String subfieldIds = s[2].replace('_', ' ');
|
|
||||||
if (subfieldIds.isEmpty()) {
|
|
||||||
subfield(" ", value.toString());
|
|
||||||
} else {
|
|
||||||
if (value instanceof List) {
|
|
||||||
List<Object> list = (List) value;
|
|
||||||
char[] ch = subfieldIds.toCharArray();
|
|
||||||
for (int i = 0; i < list.size(); i++) {
|
|
||||||
subfield(ch[i]).value(list.get(i).toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
subfield(subfieldIds, value.toString());
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
value(value.toString());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -572,17 +568,36 @@ public class MarcField implements Comparable<MarcField> {
|
||||||
} else {
|
} else {
|
||||||
indicator(indicator);
|
indicator(indicator);
|
||||||
}
|
}
|
||||||
value(value.toString());
|
if (value instanceof Collection) {
|
||||||
|
Collection<Map.Entry<String, Object>> collection = (Collection<Map.Entry<String, Object>>) value;
|
||||||
|
for (Map.Entry<String, Object> entry : collection) {
|
||||||
|
subfield(entry.getKey(), entry.getValue().toString());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
value(value.toString());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1: {
|
case 3: {
|
||||||
tag(s[0]);
|
tag(s[0]);
|
||||||
value(value.toString());
|
String indicator = s[1].replace('_', ' ');
|
||||||
break;
|
if (indicator.isEmpty()) {
|
||||||
}
|
indicator(" ");
|
||||||
case 0: {
|
} else {
|
||||||
tag(key);
|
indicator(indicator);
|
||||||
value(value.toString());
|
}
|
||||||
|
String subfieldIds = s[2].replace('_', ' ');
|
||||||
|
if (subfieldIds.isEmpty()) {
|
||||||
|
subfieldIds = " ";
|
||||||
|
}
|
||||||
|
if (value instanceof Collection) {
|
||||||
|
Collection<Map.Entry<String, Object>> collection = (Collection<Map.Entry<String, Object>>) value;
|
||||||
|
for (Map.Entry<String, Object> entry : collection) {
|
||||||
|
subfield(entry.getKey(), entry.getValue().toString());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
subfield(subfieldIds, value.toString());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -30,8 +30,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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -99,15 +97,8 @@ public class MarcRecord implements Map<String, Object> {
|
||||||
String leaderTag,
|
String leaderTag,
|
||||||
RecordLabel recordLabel) {
|
RecordLabel recordLabel) {
|
||||||
MarcRecord marcRecord = new MarcRecord(map);
|
MarcRecord marcRecord = new MarcRecord(map);
|
||||||
marcRecord.parseMap(map, ".", "", (key, value) -> {
|
marcRecord.parseMap(map, ".", "", (key, value) ->
|
||||||
if (value instanceof Collection<?>) {
|
marcRecord.marcFields.add(MarcField.builder().key(key, "\\.", value).build()));
|
||||||
MarcField.Builder builder = MarcField.builder().key(key);
|
|
||||||
((Collection<Map.Entry<String, Object>>) value).forEach(e -> builder.subfield(e.getKey(), e.getValue().toString()));
|
|
||||||
marcRecord.marcFields.add(builder.build());
|
|
||||||
} else {
|
|
||||||
marcRecord.marcFields.add(MarcField.builder().key(key, "\\.", value.toString()).build());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (map.containsKey(formatTag)) {
|
if (map.containsKey(formatTag)) {
|
||||||
marcRecord.format = map.get(formatTag).toString();
|
marcRecord.format = map.get(formatTag).toString();
|
||||||
}
|
}
|
||||||
|
@ -359,26 +350,28 @@ public class MarcRecord implements Map<String, Object> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void parseMap(Map<String, Object> source, String separator, String prefix,
|
private void parseMap(Map<String, Object> source,
|
||||||
|
String separator, String prefix,
|
||||||
BiConsumer<String, Object> consumer) {
|
BiConsumer<String, Object> consumer) {
|
||||||
|
List<Map.Entry<String, Object>> list = new LinkedList<>();
|
||||||
source.forEach((k, v) -> {
|
source.forEach((k, v) -> {
|
||||||
if (v instanceof Map) {
|
if (v instanceof Map) {
|
||||||
parseMap((Map<String, Object>) v, separator, prefix + k + separator, consumer);
|
parseMap((Map<String, Object>) v, separator, prefix + k + separator, consumer);
|
||||||
} else if (v instanceof Collection) {
|
} else if (v instanceof Collection) {
|
||||||
Collection<Object> collection = (Collection<Object>) v;
|
Collection<Object> collection = (Collection<Object>) v;
|
||||||
List<Map.Entry<String, Object>> list = new LinkedList<>();
|
|
||||||
for (Object object : collection) {
|
for (Object object : collection) {
|
||||||
if (object instanceof Map) {
|
if (object instanceof Map) {
|
||||||
parseMap((Map<String, Object>) object, separator, prefix + k + separator, (a,b) -> list.add(Map.entry(a,b)));
|
parseMap((Map<String, Object>) object, separator, prefix + k + separator, consumer);
|
||||||
} else {
|
} else {
|
||||||
list.add(Map.entry(prefix + k, object));
|
list.add(Map.entry(k, object));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Logger.getLogger("").log(Level.INFO, "list = " + list);
|
|
||||||
consumer.accept(prefix + k, list);
|
|
||||||
} else {
|
} else {
|
||||||
consumer.accept(prefix + k, v);
|
list.add(Map.entry(k, v));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (!list.isEmpty()) {
|
||||||
|
consumer.accept(prefix, list);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,9 +32,11 @@ import java.nio.charset.Charset;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.text.Normalizer;
|
import java.text.Normalizer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
@ -220,16 +222,27 @@ public class MarcRecordTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMarcRecordFromMapNested() {
|
public void testMarcRecordFromMapNested() {
|
||||||
Map<String, Object> map = Map.of("016", Map.of("7_", List.of(Map.of("2", "DE-101", "a", "010000151"), Map.of("2", "DE-600", "a", "23-1"))));
|
Map<String, Object> map = Map.of("001", "123",
|
||||||
|
"100", Map.of("_", Map.of("a", "Hello World")),
|
||||||
|
"016", Map.of("7_", List.of(Map.of("2", "DE-101", "a", "010000151"), Map.of("2", "DE-600", "a", "23-1"))));
|
||||||
MarcRecord marcRecord = MarcRecord.from(map);
|
MarcRecord marcRecord = MarcRecord.from(map);
|
||||||
Logger.getLogger("").log(Level.INFO, "marcrecord = " + marcRecord);
|
assertEquals("123", marcRecord.getFields().stream()
|
||||||
Logger.getLogger("").log(Level.INFO, "marcrecord fields = " + marcRecord.getFields());
|
.filter(m -> m.getTag().equals("001")).findFirst().get().getValue());
|
||||||
marcRecord.filter(f -> "016".equals(f.getTag()), f-> {
|
assertEquals("Hello World", marcRecord.getFields().stream()
|
||||||
Logger.getLogger("").log(Level.INFO, "f = " + f);
|
.filter(m -> m.getTag().equals("100")).findFirst().get().getFirstSubfieldValue("a"));
|
||||||
|
assertEquals(4, marcRecord.getFields().size());
|
||||||
|
List<MarcField> list = new LinkedList<>();
|
||||||
|
marcRecord.filter(f -> "016".equals(f.getTag()), list::add);
|
||||||
|
assertEquals(2, list.size());
|
||||||
|
AtomicBoolean match = new AtomicBoolean();
|
||||||
|
marcRecord.filter(f -> "016".equals(f.getTag()) && "7 ".equals(f.getIndicator()), f -> {
|
||||||
|
if ("DE-600".equals(f.getFirstSubfieldValue("2"))) {
|
||||||
|
match.set("23-1".equals(f.getFirstSubfieldValue("a")));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
assertTrue(match.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMarcRecordFromMapAsMap() throws IOException {
|
public void testMarcRecordFromMapAsMap() throws IOException {
|
||||||
Map<String, Object> map = new TreeMap<>(Map.of("001", "123",
|
Map<String, Object> map = new TreeMap<>(Map.of("001", "123",
|
||||||
|
|
Loading…
Reference in a new issue