102 lines
2.7 KiB
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);
|
|
}
|
|
}
|