Package de.chris_soft.fyllgen.ged

Source Code of de.chris_soft.fyllgen.ged.GedReader

/**
* 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);
    }
  }
}
TOP

Related Classes of de.chris_soft.fyllgen.ged.GedReader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.