All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gdv.xport.satz.model.SatzX Maven / Gradle / Ivy

Go to download

gdv-xport-lib ist die Java-Bibliothek fuer den Umgang mit dem GDV-Format. Sie erleichtert den Export und Export dieses Datenformats.

There is a newer version: 7.2.2
Show newest version
/*
 * Copyright (c) 2011-2013 by Oli B.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express orimplied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * (c)reated 09.03.2011 by Oli B. ([email protected])
 */

package gdv.xport.satz.model;

import gdv.xport.annotation.FeldInfo;
import gdv.xport.annotation.FelderInfo;
import gdv.xport.feld.Feld;
import gdv.xport.feld.NumFeld;
import gdv.xport.io.PushbackLineNumberReader;
import gdv.xport.satz.Datensatz;
import gdv.xport.satz.Teildatensatz;
import gdv.xport.satz.enums.TeildatensatzEnum;
import gdv.xport.satz.feld.FeldX;
import gdv.xport.satz.feld.MetaFeldInfo;
import gdv.xport.satz.feld.common.Kopffelder1bis7;
import gdv.xport.satz.feld.common.TeildatensatzNummer;
import gdv.xport.satz.feld.common.WagnisartLeben;
import gdv.xport.util.SatzTyp;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;

/**
 * Dies ist die gemeinsame Oberklasse aller Saetze in diesem Package, die nach
 * dem SOP-Muster aufgebaut sind. Eventuell wird diese Klasse mit der Oberklasse
 * vereinigt.
 *
 * @author oliver ([email protected])
 * @since 0.6 (09.03.2011)
 * @deprecated Enums mit Annotationen werden ab v6 nicht mehr unterstuetzt
 */
@Deprecated
public class SatzX extends Datensatz {

	private static final Logger LOG = LogManager.getLogger();

	/**
	 * Instantiiert einen neuen Datensatz.
	 *
	 * @param satzTyp         Satzart
	 * @param teildatensaetze Teildatensaetze
	 * @since 5.0
	 */
	public SatzX(SatzTyp satzTyp, List teildatensaetze) {
		super(satzTyp, teildatensaetze);
	}

	/**
	 * Instantiiert einen neuen Datensatz.
	 * 

* TODO: Wird mit v6 entfernt. *

* * @param satzart z.B. 100 * @param felder mit allen Elementen des Datensatzes * @deprecated bitte {@link SatzX#SatzX(SatzTyp, List)} verwenden */ @Deprecated public SatzX(final int satzart, final Enum[] felder) { this(SatzTyp.of(satzart), getTeildatensaetzeFor(satzart, felder)); } /** * Instantiiert einen neuen Datensatz. *

* TODO: Wird mit v6 entfernt. *

* * @param satzart z.B. 100 * @param enumClass Enumerationen-Klasse mit den Feldbeschreibungen * @deprecated bitte {@link SatzX#SatzX(SatzTyp, List)} verwenden */ @Deprecated public SatzX(final int satzart, final Class enumClass) { this(SatzTyp.of(satzart), getTeildatensaetzeFor(SatzTyp.of(satzart), enumClass)); } /** * Instantiiert einen neuen Datensatz. *

* TODO: Wird mit v6 entfernt. *

* * @param satzart z.B. 100 * @param sparte Sparte * @param felder mit allen Elementen des Datensatzes * @deprecated bitte {@link SatzX#SatzX(SatzTyp, List)} verwenden */ @Deprecated public SatzX(final int satzart, final int sparte, final Enum[] felder) { super(satzart, complete(getTeildatensaetzeFor(satzart, felder), sparte)); } /** * Instantiiert einen neuen Datensatz. *

* TODO: Wird mit v6 entfernt. *

* * @param satzart z.B. 100 * @param sparte Sparte * @param enumClass Enumerationen-Klasse mit den Feldbeschreibungen * @deprecated bitte {@link SatzX#SatzX(SatzTyp, List)} verwenden */ @Deprecated public SatzX(final int satzart, final int sparte, final Class enumClass) { super(satzart, complete(getTeildatensaetzeFor(SatzTyp.of(satzart), enumClass), sparte)); } /** * Instantiiert einen allgemeinen Datensatz fuer die angegebene Satzart und * Sparte. Dieser Konstruktor ist hauptsaechlich als Fallback fuer * Satzarten/Sparten gedacht, die noch nicht unterstuetzt werden. * * @param satzart z.B. 100 * @param sparte Sparte */ public SatzX(final int satzart, final int sparte) { this(satzart, sparte, FeldX.values()); } /** * Instantiiert einen allgemeinen Datensatz fuer die angegebene Satznummer. * * @param satzNr Satznummer mit Satzart, Sparte, Wagnisart, lfd. Nummer * @param enumClass Enum-Klasse, die den Datensatz beschreibt * @since 0.9 */ public SatzX(final SatzTyp satzNr, final Class enumClass) { super(satzNr, getTeildatensaetzeFor(satzNr, enumClass)); this.setGdvSatzartName(satzNr.toString()); if (satzNr.hasSparte()) this.setSparte(satzNr.getSparteAsString()); if (satzNr.hasGdvSatzartNummer()) this.setGdvSatzartNummer(String.valueOf(satzNr.getGdvSatzartNummer())); } private static List complete(List teildatensaetze, int sparte) { NumFeld sparteFeld = new NumFeld(Kopffelder1bis7.SPARTE); sparteFeld.setInhalt(sparte); for (Teildatensatz tds : teildatensaetze) { setUpTeildatensatz(tds, sparteFeld); } return teildatensaetze; } /** * hierdurch werden Teildatensaetze erzeugt, die ihren GdvSatzartNamen kennen */ private static List getTeildatensaetzeFor(final SatzTyp satzNr, final Class enumClass) { Enum[] constants = enumClass.getEnumConstants(); return getTeildatensaetzeFor(satzNr, constants); } /** * Setzt die Teildatensaetze mit den angegebenen Feldern auf. * * @param felder Felder fuer die Teildatensaetze. */ protected void setUpTeildatensaetze(final Enum[] felder) { super.createTeildatensaetze(getTeildatensaetzeFor(SatzTyp.of(this.getSatzart()), felder)); super.completeTeildatensaetze(); } /** * Unterklassen (wie Datensatz) sind dafuer verantwortlich, dass auch noch * die Wagnisart und die TeildatensatzNummer ueberprueft wird, ob sie noch * richtig ist oder ob da schon der naechste Satz beginnt. * * @param reader ein Reader * @param lastFeld1To7 Feld1..7 als Char-Array (42 Zeichen) der letzten Zeile oder {@code null} für ersten Teildatensatz * @return true (Default-Implementierung) * @throws IOException bei I/O-Fehlern * @since 0.9 * @see gdv.xport.satz.Satz#matchesNextTeildatensatz(PushbackLineNumberReader, char[], Character) */ @Override protected boolean matchesNextTeildatensatz(final PushbackLineNumberReader reader, char[] lastFeld1To7, Character satznummer) throws IOException { if (super.matchesNextTeildatensatz(reader, lastFeld1To7, satznummer)) { WagnisartLeben nextLineWagnisEnum = readWagnisart(reader); TeildatensatzNummer nextLineTeildatensatzNummerEnum = readTeildatensatzNummer(reader); boolean nextLineWagnisartIsSet = nextLineWagnisEnum != WagnisartLeben.NULL; boolean nextLineTeildatensatzNummerIsSet = nextLineTeildatensatzNummerEnum != TeildatensatzNummer.NULL; boolean currentLineWagnisartIsSet = this.hasWagnisart() && this.getWagnisart().trim().length() > 0; boolean currentLineTeildatensatzNummerIsSet = this.getTeildatensatzNummer().trim() .length() > 0; if (!currentLineWagnisartIsSet) { return true; } TeildatensatzNummer currentLineTeildatensatzEnum = TeildatensatzNummer.NULL; if (currentLineTeildatensatzNummerIsSet) { currentLineTeildatensatzEnum = TeildatensatzNummer.isIn(Integer.parseInt(this .getTeildatensatzNummer())); } if ((nextLineWagnisartIsSet) && (nextLineWagnisEnum == WagnisartLeben.isIn(Integer.parseInt(this.getWagnisart())))) { if (currentLineTeildatensatzNummerIsSet || nextLineTeildatensatzNummerIsSet) { return nextLineTeildatensatzNummerEnum == currentLineTeildatensatzEnum; } else { // wagnisarten sind gleich und die // Teildatensatznummer sind beide nicht gesetzt return true; } } } return false; } // /// Enum-Behandlung und Auswertung der Meta-Infos /////////////////// /** * Hier passiert die Magie: die Annotationen der uebergebenen Enum werden * ausgelesen und in eine Liste mit den Teildatensaetzen gepackt. * * @param satzart the satzart * @param felder the felder * @return eine Liste mit Teildatensaetzen */ protected static List getTeildatensaetzeFor(final int satzart, final Enum[] felder) { SortedMap tdsMap = new TreeMap<>(); List metaFeldInfos = getMetaFeldInfos(felder); for (MetaFeldInfo metaFeldInfo : metaFeldInfos) { int n = metaFeldInfo.getTeildatensatzNr(); Teildatensatz tds = tdsMap.get(n); if (tds == null) { tds = new TeildatensatzEnum(satzart, n); tdsMap.put(n, tds); } add(metaFeldInfo.getFeldEnum(), tds); } List teildatensaetze = new ArrayList<>(tdsMap.values()); setSparteFor(teildatensaetze, metaFeldInfos); return teildatensaetze; } /** * Durch die Uebergabe eines SatzTyp kann der GdvSatzartName im * Teildatensatz besetzt werden. Bei den SatzXml ist alles eleganter.. * * Hier passiert die Magie: die Annotationen der uebergebenen Enum * werden ausgelesen und in eine Liste mit den Teildatensaetzen gepackt. * * @param satzTyp the satzTyp * @param felder the felder * @return eine Liste mit Teildatensaetzen */ protected static List getTeildatensaetzeFor( final SatzTyp satzTyp, final Enum[] felder) { SortedMap tdsMap = new TreeMap<>(); List metaFeldInfos = getMetaFeldInfos(felder); for (MetaFeldInfo metaFeldInfo : metaFeldInfos) { int n = metaFeldInfo.getTeildatensatzNr(); Teildatensatz tds = tdsMap.get(n); if (tds == null) { tds = new Teildatensatz(satzTyp, n); tdsMap.put(n, tds); } add(metaFeldInfo.getFeldEnum(), tds); } List teildatensaetze = new ArrayList<>(tdsMap.values()); setSparteFor(teildatensaetze, metaFeldInfos); return teildatensaetze; } private static void setSparteFor(final List teildatensaetze, final List metaFeldInfos) { int sparte = getSparte(metaFeldInfos); if (sparte > 0) { setSparteFor(teildatensaetze, sparte); } } private static int getSparte(final List metaFeldInfos) { for (MetaFeldInfo info : metaFeldInfos) { if (info.hasSparte()) { return info.getSparte(); } } return -1; } private static void setSparteFor(final List teildatensaetze, final int sparte) { for (Teildatensatz teildatensatz : teildatensaetze) { setSparteFor(teildatensatz, sparte); } } private static void setSparteFor(final Teildatensatz tds, final int sparte) { if (!tds.hasFeld(Kopffelder1bis7.SPARTE)) { Feld spartenFeld = new NumFeld(Kopffelder1bis7.SPARTE); tds.add(spartenFeld); } tds.getFeld(Kopffelder1bis7.SPARTE.getBezeichner()) .setInhalt(sparte); } /** * Wandelt das uebergebene Array in eine Liste mit MetaFeldInfos. Seit 0.7.1 * duerfen Feld-Enums wie {@link gdv.xport.satz.feld.Feld100} auch * FelderInfo-Annotationen enthalten, die wiederum auf einen Enum verweisen. * * @param felder the felder * @return the meta feld infos */ public static List getMetaFeldInfos(final Enum[] felder) { List metaFeldInfos = new ArrayList<>(felder.length); for (Enum f : felder) { String name = f.name(); try { Field field = f.getClass().getField(name); FelderInfo info = field.getAnnotation(FelderInfo.class); if (info == null) { metaFeldInfos.add(new MetaFeldInfo(f)); } else { metaFeldInfos.addAll(getMetaFeldInfos(info)); } } catch (NoSuchFieldException nsfe) { throw new InternalError("no field " + name + " (" + nsfe + ")"); } } return metaFeldInfos; } private static List getMetaFeldInfos(final FelderInfo info) { Collection enums = getAsList(info); List metaFeldInfos = new ArrayList<>(enums.size()); for (Enum enumX : enums) { metaFeldInfos.add(new MetaFeldInfo(enumX, info)); } return metaFeldInfos; } private static Collection getAsList(final FelderInfo info) { Class enumClass = info.type(); return getAsList(enumClass.getEnumConstants()); } /** * Wandelt das uebergebene Array in eine Liste mit Felder. Seit 0.7.1 * duerfen Feld-Enums wie {@link gdv.xport.satz.feld.Feld100} auch * FelderInfo-Annotationen enthalten, die wiederum auf einen Enum verweisen. * * @param felder the felder * @return the feld info list */ private static List getAsList(final Enum[] felder) { List feldList = new ArrayList<>(felder.length); for (Enum f : felder) { String name = f.name(); try { Field field = f.getClass().getField(name); FelderInfo info = field.getAnnotation(FelderInfo.class); if (info == null) { feldList.add(f); } else { feldList.addAll(getAsList(info)); } } catch (NoSuchFieldException nsfe) { throw new InternalError("no field " + name + " (" + nsfe + ")"); } } return feldList; } /** * Leitet aus dem uebergebenen Feldelement die Parameter ab, um daraus ein * Feld anzulegen und im jeweiligen Teildatensatz einzuhaengen. Zusaetzlich * wird das Feld "Satznummer" vorbelegt, falls es in den uebergebenen * Feldern vorhanden ist. *

* TODO: Vorsatz wird noch nicht richtig behandelt, da die ersten 6 Felder * hier etwas anders behandelt wird. *

* * @param feldX das Feld-Element * @param tds der entsprechende Teildatensatz */ private static void add(final Enum feldX, final Teildatensatz tds) { FeldInfo info = MetaFeldInfo.getFeldInfo(feldX); Feld feld = Feld.createFeld(feldX, info); if (info.nr() < 7) { // TODO: diese Abfrage ist eigentlich unnoetig LOG.debug("using default settings for " + feld); } else { tds.add(feld); if (isSatznummer(feldX)) { feld.setInhalt(info.teildatensatz()); } } } private static boolean isSatznummer(final Enum feldX) { return (feldX.name().length() <= 11) && feldX.name().startsWith("SATZNUMMER"); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy