gedcom-api/src/main/java/de/nth/chronicle/gedcom/parser/RecordChunk.java

102 lines
2.7 KiB
Java

package de.nth.chronicle.gedcom.parser;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import java.util.*;
@Getter
@Setter
@Builder
public class RecordChunk {
private Map<String, RecordChunk> recordIndex;
private int lineNumber;
private String sourceLine;
private int level;
private String tag;
private String value;
private RecordChunk previous, next;
@Builder.Default
private List<RecordChunk> subRecords = new LinkedList<>();
/**
* Normalizes CONT & CONC Sub Records by appending the line value
* to the parent record line value
*/
void normalize() {
if(this.value == null) {
this.subRecords.forEach(record -> record.normalize());
return;
}
StringBuilder sb = new StringBuilder(this.value);
Set<RecordChunk> delete = new HashSet<>();
for(RecordChunk chunk : this.subRecords) {
if(chunk.getTag().equals("CONT")) {
sb.append(System.lineSeparator()).append(chunk.getValue());
delete.add(chunk);
}else if(chunk.getTag().equals("CONC")) {
sb.append(chunk.getValue());
delete.add(chunk);
}
chunk.normalize();
}
this.subRecords.removeAll(delete);
this.value = sb.toString();
}
public Optional<String> findFirstValue(String tag) {
return findFirst(tag)
.map(record -> record.getValue());
}
public Optional<RecordChunk> findFirst(String tag) {
return findIndexed(tag);
}
private Optional<RecordChunk> findIndexed(String tag) {
if(this.recordIndex == null) {
this.recordIndex = new HashMap<>();
}
if(this.recordIndex.containsKey(tag)) {
return Optional.of(this.recordIndex.get(tag));
}
return searchRecord(tag).map(record -> putIndex(tag, record));
}
private Optional<RecordChunk> searchRecord(String tag) {
String[] pathTokens = tag.split("\\.");
RecordChunk lastRecord = this;
for(String token : pathTokens) {
for(RecordChunk record : lastRecord.subRecords) {
if(record.getTag().equals(token)) {
lastRecord = record;
}
}
}
if(!lastRecord.getTag().equals(pathTokens[pathTokens.length - 1])) {
lastRecord = null;
}
return Optional.ofNullable(lastRecord);
}
private RecordChunk putIndex(String tag, RecordChunk record) {
this.recordIndex.put(tag, record);
return record;
}
@Override
public String toString() {
return String.format("%d %s %s", this.level, this.tag, this.value);
}
}