/**
* FyLLGen - A Java based tool for collecting and distributing family data
*
* Copyright (C) 2007-2011 Christian Packenius
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.chris_soft.fyllgen.ged;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.StringTokenizer;
import de.chris_soft.fyllgen.data.Family;
import de.chris_soft.fyllgen.data.Person;
import de.chris_soft.fyllgen.data.Relationship;
import de.chris_soft.fyllgen.data.RelationshipPartners;
/**
* Einlesen einer GED-Datei mit Genealogie-Daten.<br>
* http://homepages.rootsweb.ancestry.com/~pmcbride/gedcom/55gctoc.htm
* @author Christian Packenius, Juli 2008.
*/
public class GedReader {
/**
* Eingabe.
*/
private BufferedReader in = null;
/**
* Zeile und ausgelesene Inhalte.
*/
private String line; // Komplette Zeile.
private String level; // Record-Level.
private int gedRecordLevel; // Record-Level, als Integer-Wert.
private String gedRecordTag; // ZeilenBefehl.
private String gedRecordXRefID; // Angegebene Cross-Referenz-ID.
private String gedRecordParms; // Parameter hinter dem Tag.
/**
* Gr��e eines Records w�hrend der Verarbeitung.
*/
private int gedRecordSize;
/**
* Index innerhalb des Records w�hrend der Verarbeitung.
*/
private int gedRecordIndex;
/**
* Liste aller Personen.
*/
private List<Person> listPersons = new ArrayList<Person>();
private HashMap<String, Person> hmPersons = new HashMap<String, Person>();
/**
* Monatsangaben.
*/
private static final String MONTHS1 = "-jan-feb-mar-apr-may-jun-jul-aug-sep-oct-nov-dec-";
private static final String MONTHS2 = "-jan-feb-m�r-apr-mai-jun-jul-aug-sep-okt-nov-dez-";
/**
* @param in
*/
public void setInputStream(InputStream in) {
this.in = new BufferedReader(new InputStreamReader(in));
}
/**
* Einlesen des gesamten GED-Datenstroms.
* @throws IOException
* @throws GedReaderException
*/
public void read() throws IOException, GedReaderException {
// Einzelner Record (jeder Record beginnt mit einer 0-Zeile).
List<String> gedRecord = new ArrayList<String>();
// Alles einlesen, jeden Record einzeln verarbeiten.
String line;
while ((line = in.readLine()) != null) {
if (line.startsWith("0 ")) {
if (gedRecord.size() != 0) {
workRecord(gedRecord);
gedRecord.clear();
}
}
gedRecord.add(line);
}
// Letzten Record verarbeiten.
if (gedRecord.size() != 0) {
workRecord(gedRecord);
}
}
/**
* Verarbeitet einen Record, also eine Liste von eingelesenen Zeilen.
* @param gedRecord
* @throws GedReaderException
*/
private void workRecord(List<String> gedRecord) throws GedReaderException {
// CONC und CONT vorneweg verarbeiten.
for (int i = gedRecord.size() - 1; i > 0; i--) {
line = gedRecord.get(i);
testGedLine();
if (gedRecordTag.equals("conc")) {
String prev = gedRecord.get(i - 1).trim() + " " + gedRecordParms;
gedRecord.set(i - 1, prev);
gedRecord.remove(i);
}
else if (gedRecordTag.equals("cont")) {
String prev = gedRecord.get(i - 1).trim() + "\r\n" + gedRecordParms;
gedRecord.set(i - 1, prev);
gedRecord.remove(i);
}
}
// Einlesen des Records initialisieren.
gedRecordSize = gedRecord.size();
gedRecordIndex = 0;
// Level 0-Record verarbeiten.
getNextGedLine(gedRecord);
// Je nach Haupt-Tag einlesen.
if (gedRecordTag.equals("head")) {
// Ignorieren, dies ist der Datei-Head.
}
else if (gedRecordTag.equals("subm")) {
// Ignorieren, dies ist die erstellende Person.
}
else if (gedRecordTag.equals("indi")) {
readINDI(gedRecord);
}
else if (gedRecordTag.equals("fam")) {
readFAM(gedRecord);
}
else if (gedRecordTag.equals("trlr")) {
// Dateiende, ignorieren.
return;
}
else {
throw new GedReaderException("Unbekanntes 0-Tag <" + gedRecordTag + "> gefunden!", line);
}
}
/**
* Einlesen einer Familienzugeh�rigkeit.
* @param gedRecord
* @throws GedReaderException
*/
private void readFAM(List<String> gedRecord) throws GedReaderException {
// Elternteile und Partnerschaft.
String husb = null, wife = null;
RelationshipPartners partnership = null;
// TODO - F�r den Fall, dass die Familien vor den Personen in der GED-Datei
// stehen, k�nnte man auch eine Liste aller Partnerschaften und so aufbauen
// und diese erst nach dem Einlesen einpflegen.
// TODO - Dann d�rfte man aber nur mit IDs arbeiten, nicht mit
// Person-Objekten.
// Personendaten einlesen.
while (getNextGedLine(gedRecord) != null) {
// Je nach Level agieren.
if (gedRecordLevel == 1) {
if (gedRecordTag.equals("husb")) {
husb = gedRecordParms;
partnership = setPartnership(husb, wife);
}
else if (gedRecordTag.equals("wife")) {
wife = gedRecordParms;
partnership = setPartnership(husb, wife);
}
else if (gedRecordTag.equals("note")) {
Person person;
if (husb != null && (person = hmPersons.get(husb)) != null) {
String notes = person.getValueView(Person.NOTES);
notes += "\r\nEinzelnotiz: " + gedRecordParms;
person.setLoadedValue(Person.NOTES, notes);
}
if (wife != null && (person = hmPersons.get(wife)) != null) {
String notes = person.getValueView(Person.NOTES);
notes += "\r\nEinzelnotiz: " + gedRecordParms;
person.setLoadedValue(Person.NOTES, notes);
}
}
else if (gedRecordTag.equals("chil")) {
String child = gedRecordParms;
if (hmPersons.get(child) == null) {
return;
// throw new GedReaderException("Unbekanntes Kind " + child +
// " gefunden!", line);
}
if (husb != null && hmPersons.get(husb) != null) {
hmPersons.get(husb).addChild(hmPersons.get(child));
}
if (wife != null && hmPersons.get(wife) != null) {
hmPersons.get(wife).addChild(hmPersons.get(child));
}
}
else if (gedRecordTag.equals("marr")) {
if (partnership != null) {
readFAM_MARR(gedRecord, partnership);
}
else {
ignoreSubTags(gedRecord);
}
}
else if (gedRecordTag.equals("div")) {
if (partnership != null) {
readFAM_DIV(gedRecord, partnership);
}
else {
ignoreSubTags(gedRecord);
}
}
else if (gedRecordTag.equals("chan")) {
// Ignorieren - CHAN ist das letzte �nderungsdatum des Records.
ignoreSubTags(gedRecord);
}
else if (gedRecordTag.equals("rfn") || gedRecordTag.equals("ordi") || gedRecordTag.equals("_liv")
|| gedRecordTag.equals("marb")) {
// Ignorieren.
ignoreSubTags(gedRecord);
}
else {
throw new GedReaderException("Unbekanntes Level 1-FAM-Tag <" + gedRecordTag + "> gefunden!", line);
}
}
else {
throw new GedReaderException("Unbekanntes Level " + gedRecordLevel + " gefunden!", line);
}
}
}
private void readFAM_DIV(List<String> gedRecord, RelationshipPartners partnership) throws GedReaderException {
int lev = gedRecordLevel + 1;
String date = null, place = null, type = "";
while (getNextGedLine(gedRecord) != null && gedRecordLevel == lev) {
if (gedRecordTag.equals("date")) {
date = getDateFromParms();
}
else if (gedRecordTag.equals("plac")) {
place = gedRecordParms;
}
else if (gedRecordTag.equals("type")) {
type = gedRecordParms;
}
else {
throw new GedReaderException("Unbekanntes Level 2-FAM-DIV-Tag <" + gedRecordTag + "> gefunden!", line);
}
}
if (gedRecordLevel != 0) {
gedRecordIndex--;
}
if (type.toLowerCase().equals("divorced")) {
partnership.setValue(Relationship.TYPE, RelationshipPartners.DIVORCE);
if (date != null) {
partnership.setValue(RelationshipPartners.ENDDATE, date);
}
if (place != null) {
partnership.setValue(RelationshipPartners.ENDPLACE, place);
}
}
}
/**
* Liest eine Partnerschaft (fast immer Ehe) ein.
* @throws GedReaderException
*/
private void readFAM_MARR(List<String> gedRecord, RelationshipPartners partnership) throws GedReaderException {
int lev = gedRecordLevel + 1;
while (getNextGedLine(gedRecord) != null && gedRecordLevel == lev) {
if (gedRecordTag.equals("date")) {
String date = getDateFromParms();
partnership.setValue(RelationshipPartners.STARTDATE, date);
}
else if (gedRecordTag.equals("plac")) {
partnership.setValue(RelationshipPartners.STARTPLACE, gedRecordParms);
}
else if (gedRecordTag.equals("type")) {
if (gedRecordParms.toLowerCase().equals("marriage")) {
partnership.setValue(Relationship.TYPE, RelationshipPartners.MARRIAGE);
}
else {
throw new GedReaderException("Unbekannter Partnerschaftstyp <" + gedRecordParms + "> gefunden!", line);
}
}
else if (gedRecordTag.equals("sour")) {
ignoreSubTags(gedRecord);
}
else {
throw new GedReaderException("Unbekanntes Level 2-FAM-MARR-Tag <" + gedRecordTag + "> gefunden!", line);
}
}
if (gedRecordLevel != 0) {
gedRecordIndex--;
}
}
private RelationshipPartners setPartnership(String husb, String wife) {
if (husb == null || husb.length() == 0) {
return null;
}
if (wife == null || wife.length() == 0) {
return null;
}
Person pHusb = hmPersons.get(husb);
Person pWife = hmPersons.get(wife);
return pHusb.addPartner(pWife, RelationshipPartners.MARRIAGE);
}
/**
* Record �ber eine Person (also ein Individuum) verarbeiten.
* @param gedRecord
* @throws GedReaderException
*/
private void readINDI(List<String> gedRecord) throws GedReaderException {
// Person erzeugen und speichern.
Person person = new Person();
listPersons.add(person);
if (gedRecordXRefID != null) {
person.setLoadedValue(Person.XREFID, gedRecordXRefID);
hmPersons.put(gedRecordXRefID, person);
}
// Personendaten einlesen.
while (getNextGedLine(gedRecord) != null) {
// Je nach Level agieren.
if (gedRecordLevel == 1) {
if (gedRecordTag.equals("name")) {
readINDI_NAME(gedRecord, person);
}
else if (gedRecordTag.equals("sex")) {
readINDI_SEX(person);
}
else if (gedRecordTag.equals("chan")) {
// CHAN = Letzte �nderung am Datensatz - ignorieren.
ignoreSubTags(gedRecord);
}
else if (gedRecordTag.equals("birt")) {
readINDI_BIRT(gedRecord, person);
}
else if (gedRecordTag.equals("deat")) {
readINDI_DEAT(gedRecord, person);
}
else if (gedRecordTag.equals("crem")) {
readINDI_CREM(gedRecord, person);
}
else if (gedRecordTag.equals("bapm") || gedRecordTag.equals("chr")) {
String notes = person.getValueView(Person.NOTES);
notes += "\r\nTaufe:";
notes = readINDI_SingleEvent(notes, gedRecord);
person.setLoadedValue(Person.NOTES, notes);
}
else if (gedRecordTag.equals("conf")) {
String notes = person.getValueView(Person.NOTES);
notes += "\r\nKonfirmation:";
notes = readINDI_SingleEvent(notes, gedRecord);
person.setLoadedValue(Person.NOTES, notes);
}
else if (gedRecordTag.equals("addr")) {
String notes = person.getValueView(Person.NOTES);
notes += "\r\nAdresse: " + gedRecordParms;
person.setLoadedValue(Person.NOTES, notes);
readINDI_ADDR(gedRecord, person);
}
else if (gedRecordTag.equals("buri")) {
String notes = person.getValueView(Person.NOTES);
notes += "\r\nBegr�bnis:";
notes = readINDI_SingleEvent(notes, gedRecord);
person.setLoadedValue(Person.NOTES, notes);
}
else if (gedRecordTag.equals("note")) {
String notes = person.getValueView(Person.NOTES);
notes += "\r\nEinzelnotiz: " + gedRecordParms;
person.setLoadedValue(Person.NOTES, notes);
}
else if (gedRecordTag.equals("even")) {
String notes = person.getValueView(Person.NOTES);
notes += "\r\nEreignis:";
notes = readINDI_SingleEvent(notes, gedRecord);
person.setLoadedValue(Person.NOTES, notes);
}
else if (gedRecordTag.equals("adop")) {
String notes = person.getValueView(Person.NOTES);
notes += "\r\nAdoption:";
notes = readINDI_SingleEvent(notes, gedRecord);
person.setLoadedValue(Person.NOTES, notes);
}
else if (gedRecordTag.equals("ordn")) {
String notes = person.getValueView(Person.NOTES);
notes += "\r\nOrdination:";
notes = readINDI_SingleEvent(notes, gedRecord);
person.setLoadedValue(Person.NOTES, notes);
}
else if (gedRecordTag.equals("famc") || gedRecordTag.equals("fams")) {
// Familienzugeh�rigkeiten k�nnen ignoriert werden, da die XREF-IDs
// dies schon zeigen werden.
}
else if (gedRecordTag.equals("rfn") || gedRecordTag.equals("refn") || gedRecordTag.equals("_comm")) {
// Ignorieren, gibt eindeutige Nummer eines Individuums an.
}
else if (gedRecordTag.equals("occu")) {
person.setLoadedValue(Person.JOB, gedRecordParms);
}
else if (gedRecordTag.equals("titl")) {
String notes = person.getValueView(Person.NOTES);
notes += "\r\nTitel: " + gedRecordParms;
person.setLoadedValue(Person.NOTES, notes);
}
else {
throw new GedReaderException("Unbekanntes Level 1-INDI-Tag <" + gedRecordTag + "> gefunden!", line);
}
}
else {
throw new GedReaderException("Unbekanntes Level " + gedRecordLevel + " gefunden!", line);
}
}
}
/**
* Liest die Adresse einer Person ein.
* @throws GedReaderException
*/
private void readINDI_ADDR(List<String> gedRecord, Person person) throws GedReaderException {
while (getNextGedLine(gedRecord) != null && gedRecordLevel == 2) {
if (gedRecordTag.equals("phon")) {
String notes = person.getValueView(Person.NOTES);
notes += "\r\nTelefonnummer: " + gedRecordParms;
person.setLoadedValue(Person.NOTES, notes);
}
else {
throw new GedReaderException("Unbekanntes Level 2-INDI-ADDR-Tag <" + gedRecordTag + "> gefunden!", line);
}
}
if (gedRecordLevel != 0) {
gedRecordIndex--;
}
}
/**
* Liest einen Event ein. Die darin befindlichen Daten werden an den
* angegebenen String angehangen. Dieser wird dann komplett zur�ck gegeben.
* @param notes Notizen-String.
* @param gedRecord
* @return Neuer Notizen-String.
* @throws GedReaderException
*/
private String readINDI_SingleEvent(String notes, List<String> gedRecord) throws GedReaderException {
int lev = gedRecordLevel + 1;
while (getNextGedLine(gedRecord) != null && gedRecordLevel == lev) {
if (gedRecordTag.equals("date")) {
String date = getDateFromParms();
notes += "\r\nDatum: " + date;
}
else if (gedRecordTag.equals("plac")) {
notes += "\r\nOrt: " + gedRecordParms;
}
else if (gedRecordTag.equals("type")) {
notes += "\r\nTyp: " + gedRecordParms;
}
else if (gedRecordTag.equals("reli")) {
notes += "\r\nKonfession: " + gedRecordParms;
}
else if (gedRecordTag.equals("note")) {
notes += "\r\nNotiz: " + gedRecordParms;
}
else if (gedRecordTag.equals("sour")) {
notes = readINDI_SingleEvent_SOUR(notes, gedRecord);
}
else {
throw new GedReaderException("Unbekanntes Level 2-INDI-XYZ-Tag <" + gedRecordTag + "> gefunden!", line);
}
}
if (gedRecordLevel != 0) {
gedRecordIndex--;
}
return notes;
}
private String readINDI_SingleEvent_SOUR(String notes, List<String> gedRecord) throws GedReaderException {
while (getNextGedLine(gedRecord) != null && gedRecordLevel == 3) {
if (gedRecordTag.equals("text")) {
notes += "\r\nNotiz zur Quelle: " + gedRecordParms;
}
else {
throw new GedReaderException("Unbekanntes Level 3-INDI-XYZ-SOUR-Tag <" + gedRecordTag + "> gefunden!", line);
}
}
if (gedRecordLevel != 0) {
gedRecordIndex--;
}
return notes;
}
private void readINDI_SEX(Person person) {
String sex = gedRecordParms.toLowerCase();
if (sex.equals("m")) {
person.setLoadedValue(Person.SEX, Person.MALE);
}
else if (sex.equals("f")) {
person.setLoadedValue(Person.SEX, Person.FEMALE);
}
else {
person.setLoadedValue(Person.SEX, Person.UNKNOWN);
}
// else {
// throw new GedReaderException("Unbekanntes Geschlecht <" + gedRecordParms+
// "> gefunden!", line);
// }
}
private void readINDI_NAME(List<String> gedRecord, Person person) throws GedReaderException {
String name = gedRecordParms;
int i;
while ((i = name.indexOf('/')) > 0) {
name = name.substring(0, i) + " " + name.substring(i + 1);
}
while ((i = name.indexOf(" ")) >= 0) {
name = name.substring(0, i) + name.substring(i + 1);
}
name = name.trim();
while (name.startsWith(".")) {
name = name.substring(1);
}
person.setLoadedValue(Person.NAME, name);
while (getNextGedLine(gedRecord) != null && gedRecordLevel == 2) {
if (gedRecordTag.equals("nick") || gedRecordTag.equals("_alia") || gedRecordTag.equals("_aka")) {
// Ignorieren.
}
else {
throw new GedReaderException("Unbekanntes Level 2-INDI-NAME-Tag <" + gedRecordTag + "> gefunden!", line);
}
}
if (gedRecordLevel != 0) {
gedRecordIndex--;
}
}
/**
* Liest den Geburtstag ein.
* @param gedRecord
* @param person
* @throws GedReaderException
*/
private void readINDI_BIRT(List<String> gedRecord, Person person) throws GedReaderException {
while (getNextGedLine(gedRecord) != null && gedRecordLevel == 2) {
if (gedRecordTag.equals("date")) {
String date = getDateFromParms();
person.setLoadedValue(Person.BIRTHDAY, date);
}
else if (gedRecordTag.equals("time")) {
String notes = person.getValueView(Person.NOTES);
notes += "\r\nGeburtszeitpunkt: " + gedRecordParms;
person.setLoadedValue(Person.NOTES, notes);
}
else if (gedRecordTag.equals("plac")) {
person.setLoadedValue(Person.BIRTHPLACE, gedRecordParms);
}
else if (gedRecordTag.equals("note")) {
String notes = person.getValueView(Person.NOTES);
notes += "\r\nNotiz zur Geburt: " + gedRecordParms;
person.setLoadedValue(Person.NOTES, notes);
}
else if (gedRecordTag.equals("sour")) {
readINDI_BIRT_SOUR(gedRecord, person);
}
else {
throw new GedReaderException("Unbekanntes Level 2-INDI-BIRT-Tag <" + gedRecordTag + "> gefunden!", line);
}
}
if (gedRecordLevel != 0) {
gedRecordIndex--;
}
}
private void readINDI_BIRT_SOUR(List<String> gedRecord, Person person) throws GedReaderException {
while (getNextGedLine(gedRecord) != null && gedRecordLevel == 3) {
if (gedRecordTag.equals("text")) {
String notes = person.getValueView(Person.NOTES);
notes += "\r\nNotiz zur Quelle: " + gedRecordParms;
person.setLoadedValue(Person.NOTES, notes);
}
else if (gedRecordTag.equals("refn")) {
// Ignorieren.
}
else {
throw new GedReaderException("Unbekanntes Level 3-INDI-BIRT-SOUR-Tag <" + gedRecordTag + "> gefunden!", line);
}
}
if (gedRecordLevel != 0) {
gedRecordIndex--;
}
}
/**
* Liest Informationen zum Tod einer Person ein.
* @param gedRecord
* @param person
* @throws GedReaderException
*/
private void readINDI_DEAT(List<String> gedRecord, Person person) throws GedReaderException {
while (getNextGedLine(gedRecord) != null && gedRecordLevel == 2) {
if (gedRecordTag.equals("date")) {
String date = getDateFromParms();
person.setLoadedValue(Person.DEATHDAY, date);
}
else if (gedRecordTag.equals("time")) {
String notes = person.getValueView(Person.NOTES);
notes += "\r\nTodeszeitpunkt: " + gedRecordParms;
person.setLoadedValue(Person.NOTES, notes);
}
else if (gedRecordTag.equals("plac")) {
person.setLoadedValue(Person.DEATHPLACE, gedRecordParms);
}
else if (gedRecordTag.equals("note")) {
String notes = person.getValueView(Person.NOTES);
notes += "\r\nNotiz zum Exitus: " + gedRecordParms;
person.setLoadedValue(Person.NOTES, notes);
}
else if (gedRecordTag.equals("sour")) {
readINDI_DEAT_SOUR(gedRecord, person);
}
else {
throw new GedReaderException("Unbekanntes Level 2-INDI-DEAT-Tag <" + gedRecordTag + "> gefunden!", line);
}
}
if (gedRecordLevel != 0) {
gedRecordIndex--;
}
}
/**
* Liest Informationen zum Tod einer Person ein.
* @param gedRecord
* @param person
* @throws GedReaderException
*/
private void readINDI_CREM(List<String> gedRecord, Person person) throws GedReaderException {
while (getNextGedLine(gedRecord) != null && gedRecordLevel == 2) {
if (gedRecordTag.equals("date")) {
String notes = person.getValueView(Person.NOTES);
notes += "\r\nVerbrennungsdatum: " + gedRecordParms;
person.setLoadedValue(Person.NOTES, notes);
}
else if (gedRecordTag.equals("time")) {
String notes = person.getValueView(Person.NOTES);
notes += "\r\nVerbrennungszeitpunkt: " + gedRecordParms;
person.setLoadedValue(Person.NOTES, notes);
}
else if (gedRecordTag.equals("plac")) {
String notes = person.getValueView(Person.NOTES);
notes += "\r\nVerbrennungsort: " + gedRecordParms;
person.setLoadedValue(Person.NOTES, notes);
}
else if (gedRecordTag.equals("note")) {
String notes = person.getValueView(Person.NOTES);
notes += "\r\nVerbrennungsnotiz: " + gedRecordParms;
person.setLoadedValue(Person.NOTES, notes);
}
else {
throw new GedReaderException("Unbekanntes Level 2-INDI-DEAT-Tag <" + gedRecordTag + "> gefunden!", line);
}
}
if (gedRecordLevel != 0) {
gedRecordIndex--;
}
}
private void readINDI_DEAT_SOUR(List<String> gedRecord, Person person) throws GedReaderException {
while (getNextGedLine(gedRecord) != null && gedRecordLevel == 3) {
if (gedRecordTag.equals("text")) {
String notes = person.getValueView(Person.NOTES);
notes += "\r\nNotiz zur Quelle: " + gedRecordParms;
person.setLoadedValue(Person.NOTES, notes);
}
else if (gedRecordTag.equals("refn")) {
// Ignorieren.
}
else {
throw new GedReaderException("Unbekanntes Level 3-INDI-DEAT-SOUR-Tag <" + gedRecordTag + "> gefunden!", line);
}
}
if (gedRecordLevel != 0) {
gedRecordIndex--;
}
}
/**
* Ermittelt aus dem aktuellen Zeilenparameter ein Datum.
* @return Datum in String-Form.
* @throws GedReaderException
*/
private String getDateFromParms() throws GedReaderException {
// Da die Angaben innerhalb eines Datums in verschiedener Reihenfolge
// vorkommen k�nnen,
// muss eine Schleife erzeugt werden.
String tag = "?", monat = "?", jahr = "?";
String s = gedRecordParms.trim().toLowerCase();
// Token in Array einlesen.
StringTokenizer tokenizer = new StringTokenizer(s);
int tokenCount = tokenizer.countTokens();
while (tokenCount > 3) {
String dummy = tokenizer.nextToken();
// Nicht-numerische Angaben vorneweg werden ignoriert.
if (dummy.charAt(0) >= '0' && dummy.charAt(0) <= '9') {
return "?.?.?";
}
tokenCount = tokenizer.countTokens();
}
String[] sa = new String[] { "", "", "" };
int tc = 0;
while (tokenizer.hasMoreTokens()) {
sa[tc++] = tokenizer.nextToken();
}
// Token einlesen.
while (tc > 0) {
// Monatsangabe?
if ((sa[0].charAt(0) < '0' || sa[0].charAt(0) > '9') && monat.equals("?")) {
int iMonat = MONTHS1.indexOf("-" + sa[0] + "-");
if (iMonat < 0) {
iMonat = MONTHS2.indexOf("-" + sa[0] + "-");
}
if (iMonat < 0) {
// Ignorieren.
}
else {
iMonat >>= 2;
iMonat++;
monat = Integer.toString(iMonat);
}
}
// Jahr?
else if (tc == 1 && jahr.equals("?")) {
try {
jahr = Integer.toString(Integer.parseInt(sa[0]));
}
catch (Exception e) {
// Ignorieren.
}
}
// Tag?
else if (tag.equals("?")) {
try {
tag = Integer.toString(Integer.parseInt(sa[0]));
}
catch (Exception e) {
// Ignorieren.
}
}
else {
throw new GedReaderException("Unbekannte Datumsangabe!", line);
}
tc--;
sa[0] = sa[1];
sa[1] = sa[2];
}
return tag + "." + monat + "." + jahr;
}
/**
* Ignoriert alle untergeordneten Zeilen zur aktuellen Zeile.
* @param gedRecord
* @throws GedReaderException
*/
private void ignoreSubTags(List<String> gedRecord) throws GedReaderException {
int lev = gedRecordLevel;
String s;
while ((s = getNextGedLine(gedRecord)) != null && gedRecordLevel > lev) {
// Weiter machen.
}
if (s != null) {
gedRecordIndex--;
}
}
/**
* Holt die n�chste Zeile aus dem Record und nimmt sie auseinander.
* @param gedRecord
* @throws GedReaderException
*/
private String getNextGedLine(List<String> gedRecord) throws GedReaderException {
if (gedRecordIndex == gedRecordSize) {
line = null;
level = null;
gedRecordLevel = 0;
gedRecordTag = null;
gedRecordXRefID = null;
gedRecordParms = null;
}
else {
line = gedRecord.get(gedRecordIndex++);
testGedLine();
}
return line;
}
/**
* Pr�ft, ob eine GED-Zeile in Ordnung ist.
* @throws GedReaderException
*/
private void testGedLine() throws GedReaderException {
// Vorbereitungen.
int i = 0;
int lineLength = line.length();
// Level einlesen.
level = "";
while (i < lineLength && line.charAt(i) >= '0' && line.charAt(i) <= '9') {
level += line.charAt(i++);
}
if (level.length() == 0) {
throw new GedReaderException("Kein Level angegeben!", line);
}
if (level.length() > 2) {
throw new GedReaderException("Level ist zu hoch!", line);
}
if (level.length() == 2 && level.charAt(0) == '0') {
throw new GedReaderException("Illegaler Level angegeben!", line);
}
gedRecordLevel = Integer.parseInt(level);
// Delimiter einlesen.
if (line.charAt(i++) != ' ') {
throw new GedReaderException("Vermisse Space hinter Level-Angabe!", line);
}
// xred_id einlesen.
if (line.charAt(i) == '@') {
int k = line.indexOf('@', i + 1);
if (k < 0) {
throw new GedReaderException("Cross-Reference ohne Ende-Kennzeichen!", line);
}
k++;
gedRecordXRefID = line.substring(i, k);
i = k;
}
else {
gedRecordXRefID = null;
}
// Die folgenden Delimiter sind optional.
while (i < lineLength && line.charAt(i) == ' ') {
i++;
}
// Das eigentliche Tag einlesen.
int k = line.indexOf(' ', i);
if (k < 0) {
gedRecordTag = line.substring(i).toLowerCase();
gedRecordParms = "";
return;
}
gedRecordTag = line.substring(i, k).toLowerCase();
i = k;
while (i < lineLength && line.charAt(i) == ' ') {
i++;
}
// Optionale Parameter einlesen.
gedRecordParms = line.substring(i).trim();
}
/**
* F�llt alle Personen in die angegebene Familie.
* @param mergeFamily
*/
public void fillFamily(Family mergeFamily) {
for (Person person : listPersons) {
mergeFamily.addNewPerson(person);
}
}
}