add methods to initialize MarcField and MarcRecord from Java Maps
This commit is contained in:
parent
503647ec9b
commit
9b1bac1e6f
5 changed files with 142 additions and 9 deletions
|
@ -1,5 +1,5 @@
|
||||||
group = org.xbib
|
group = org.xbib
|
||||||
name = marc
|
name = marc
|
||||||
version = 2.7.1
|
version = 2.8.0
|
||||||
|
|
||||||
org.gradle.warning.mode = ALL
|
org.gradle.warning.mode = ALL
|
||||||
|
|
|
@ -531,6 +531,57 @@ public class MarcField implements Comparable<MarcField> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A key is a compact representation of tag/indicator/value
|
||||||
|
* @param key
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Builder key(String key, String separator, String value) {
|
||||||
|
String[] s = key.split(separator);
|
||||||
|
switch (s.length) {
|
||||||
|
case 3: {
|
||||||
|
tag(s[0]);
|
||||||
|
String indicator = s[1].replace('_', ' ');
|
||||||
|
if (indicator.isEmpty()) {
|
||||||
|
indicator(" ");
|
||||||
|
} else {
|
||||||
|
indicator(indicator);
|
||||||
|
}
|
||||||
|
String subfieldId = s[2].replace('_', ' ');
|
||||||
|
if (subfieldId.isEmpty()) {
|
||||||
|
subfield(" ", value);
|
||||||
|
} else {
|
||||||
|
subfield(subfieldId, value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
tag(s[0]);
|
||||||
|
String indicator = s[1].replace('_', ' ');
|
||||||
|
if (indicator.isEmpty()) {
|
||||||
|
indicator(" ");
|
||||||
|
} else {
|
||||||
|
indicator(indicator);
|
||||||
|
}
|
||||||
|
value(value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1: {
|
||||||
|
tag(s[0]);
|
||||||
|
value(value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0: {
|
||||||
|
tag(key);
|
||||||
|
value(value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("key specification is invalid: " + key + " length = " + s.length);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder setValidator(MarcFieldValidator validator) {
|
public Builder setValidator(MarcFieldValidator validator) {
|
||||||
this.validator = validator;
|
this.validator = validator;
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -21,11 +21,13 @@ 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.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -37,14 +39,19 @@ public class MarcRecord extends LinkedHashMap<String, Object> {
|
||||||
|
|
||||||
private static final MarcRecord EMPTY_RECORD = Marc.builder().buildRecord();
|
private static final MarcRecord EMPTY_RECORD = Marc.builder().buildRecord();
|
||||||
|
|
||||||
private final String format;
|
private String format;
|
||||||
|
|
||||||
private final String type;
|
private String type;
|
||||||
|
|
||||||
private final transient RecordLabel recordLabel;
|
private transient RecordLabel recordLabel;
|
||||||
|
|
||||||
private final transient List<MarcField> marcFields;
|
private final transient List<MarcField> marcFields;
|
||||||
|
|
||||||
|
private MarcRecord(Map<String, Object> map) {
|
||||||
|
super(map);
|
||||||
|
this.marcFields = new LinkedList<>();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a MARC record. Use {@link Marc.Builder} to create a MARC record.
|
* Create a MARC record. Use {@link Marc.Builder} to create a MARC record.
|
||||||
*
|
*
|
||||||
|
@ -54,8 +61,11 @@ public class MarcRecord extends LinkedHashMap<String, Object> {
|
||||||
* @param marcFields the MARC field
|
* @param marcFields the MARC field
|
||||||
* @param lightweight true if MARC record fields should not be entered into the underlying hash map.
|
* @param lightweight true if MARC record fields should not be entered into the underlying hash map.
|
||||||
*/
|
*/
|
||||||
public MarcRecord(String format, String type, RecordLabel recordLabel,
|
public MarcRecord(String format,
|
||||||
List<MarcField> marcFields, boolean lightweight) {
|
String type,
|
||||||
|
RecordLabel recordLabel,
|
||||||
|
List<MarcField> marcFields,
|
||||||
|
boolean lightweight) {
|
||||||
super();
|
super();
|
||||||
this.format = format;
|
this.format = format;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
@ -64,9 +74,6 @@ public class MarcRecord extends LinkedHashMap<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;
|
||||||
if (marcFields == null) {
|
|
||||||
throw new NullPointerException("fields must not be null");
|
|
||||||
}
|
|
||||||
if (!lightweight) {
|
if (!lightweight) {
|
||||||
createMap();
|
createMap();
|
||||||
}
|
}
|
||||||
|
@ -80,6 +87,33 @@ public class MarcRecord extends LinkedHashMap<String, Object> {
|
||||||
return EMPTY_RECORD;
|
return EMPTY_RECORD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static MarcRecord from(Map<String, Object> map) {
|
||||||
|
return from(map, FORMAT_TAG, TYPE_TAG, LEADER_TAG, RecordLabel.EMPTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MarcRecord from(Map<String, Object> map,
|
||||||
|
String formatTag,
|
||||||
|
String typeTag,
|
||||||
|
String leaderTag,
|
||||||
|
RecordLabel recordLabel) {
|
||||||
|
MarcRecord marcRecord = new MarcRecord(map);
|
||||||
|
marcRecord.parseMap(map, ".", "", (key, value) -> {
|
||||||
|
marcRecord.marcFields.add(MarcField.builder().key(key, "\\.", value.toString()).build());
|
||||||
|
});
|
||||||
|
if (map.containsKey(formatTag)) {
|
||||||
|
marcRecord.format = map.get(formatTag).toString();
|
||||||
|
}
|
||||||
|
if ( map.containsKey(typeTag)) {
|
||||||
|
marcRecord.type = map.get(typeTag).toString();
|
||||||
|
}
|
||||||
|
if (map.containsKey(leaderTag)) {
|
||||||
|
marcRecord.recordLabel = RecordLabel.builder().from(map.get(leaderTag).toString()).build();
|
||||||
|
} else {
|
||||||
|
marcRecord.recordLabel = recordLabel;
|
||||||
|
}
|
||||||
|
return marcRecord;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the MARC record format.
|
* Return the MARC record format.
|
||||||
*
|
*
|
||||||
|
@ -213,4 +247,24 @@ public class MarcRecord extends LinkedHashMap<String, Object> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private void parseMap(Map<String, Object> source, String separator, String prefix, BiConsumer<String, Object> consumer) {
|
||||||
|
source.forEach((k, v) -> {
|
||||||
|
if (v instanceof Map) {
|
||||||
|
parseMap((Map<String, Object>) v, separator, prefix + k + separator, consumer);
|
||||||
|
} else if (v instanceof Collection) {
|
||||||
|
Collection<Object> collection = (Collection<Object>) v;
|
||||||
|
for (Object object : collection) {
|
||||||
|
if (object instanceof Map) {
|
||||||
|
parseMap((Map<String, Object>) object, separator, prefix + k + separator, consumer);
|
||||||
|
} else {
|
||||||
|
consumer.accept(prefix + k, object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
consumer.accept(prefix + k, v);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -249,4 +249,22 @@ public class MarcFieldTest {
|
||||||
assertNull(marcField.getFirstSubfield().getValue());
|
assertNull(marcField.getFirstSubfield().getValue());
|
||||||
assertNull(marcField.getLastSubfield().getValue());
|
assertNull(marcField.getLastSubfield().getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMarcFieldFromKey() {
|
||||||
|
MarcField marcField = MarcField.builder().key("100.__.a", "\\.", "Hello World").build();
|
||||||
|
assertFalse(marcField.isControl());
|
||||||
|
assertEquals("100", marcField.getTag());
|
||||||
|
assertEquals(" ", marcField.getIndicator());
|
||||||
|
assertEquals("Hello World", marcField.getFirstSubfieldValue("a"));
|
||||||
|
marcField = MarcField.builder().key("001._._", "\\.", "123").build();
|
||||||
|
assertTrue(marcField.isControl());
|
||||||
|
assertEquals("001", marcField.getTag());
|
||||||
|
assertEquals(" ", marcField.getIndicator());
|
||||||
|
assertEquals("123", marcField.getFirstSubfieldValue(" "));
|
||||||
|
marcField = MarcField.builder().key("001", "\\.", "123").build();
|
||||||
|
assertTrue(marcField.isControl());
|
||||||
|
assertEquals("001", marcField.getTag());
|
||||||
|
assertEquals("123", marcField.getValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import java.io.InputStream;
|
||||||
import java.nio.charset.Charset;
|
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.Map;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@ -210,4 +211,13 @@ public class MarcRecordTest {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMarcRecordFromMap() {
|
||||||
|
Map<String, Object> map = Map.of("001", "123",
|
||||||
|
"100", Map.of("_", Map.of("a", "Hello World")));
|
||||||
|
MarcRecord marcRecord = MarcRecord.from(map);
|
||||||
|
assertEquals("123", marcRecord.getFields().stream().filter(m -> m.getTag().equals("001")).findFirst().get().getValue());
|
||||||
|
assertEquals("Hello World", marcRecord.getFields().stream().filter(m -> m.getTag().equals("100")).findFirst().get().getFirstSubfieldValue("a"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue