gdv.xport.config.Config Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gdv-xport-lib Show documentation
Show all versions of gdv-xport-lib Show documentation
gdv-xport-lib ist die Java-Bibliothek fuer den Umgang mit dem GDV-Format.
Sie erleichtert den Export und Export dieses Datenformats.
/*
* Copyright (c) 2009 - 2023 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 08.10.2009 by Oli B. ([email protected])
*/
package gdv.xport.config;
import gdv.xport.feld.*;
import gdv.xport.satz.xml.FeldXml;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
/**
* Ueber diese Klassen koennen Default-Werte abgefragt und das Verhalten der
* Anwendung gesteuert werden. Mit v5.3 wurde die Klasse umgebaut, um
* verschiedene Konfigurationen zu unterstuetzen.
*
* Ueber die Option "-Dgdv.config=..." koennen eigene Property-Dateien fuer
* die Vorbelegung angegeben werden. So kann mit
*
*
* -Dgdv.config=/gdv/xport/config/experimental.properties
*
*
* das Verhalten fuer v6 eingestellt werden, in der sich z.B. das Verhalten von
* Setzen von Feldern mit zu grossen Werten aendern wird. Einzelne Properties
* koennen aber auch durch SystemProperties (z.B. "-Dgdv.feld.truncate=true")
* uebersteuert werden.
*
*
* @author oliver
* @since 08.10.2009
*/
public final class Config implements Serializable {
private static final Logger LOG = LogManager.getLogger(Config.class);
private static Config instance = new Config();
/** Standard-Encoding ist "ISO-8859-1". */
public static final Charset DEFAULT_ENCODING = StandardCharsets.ISO_8859_1;
/** Standard-Encoding als String. */
public static final String DEFAULT_ENCODING_NAME = DEFAULT_ENCODING.toString();
/** Falls VUNummer nicht gesetzt ist, wird dies als Dummy eingesetzt. */
public static final String DUMMY_VU_NUMMER = "DUMMY";
/** Property-Name fuer die VU-Nummer. */
public static final String GDV_VU_NUMMER = "gdv.VU-Nummer";
/** Default-Konfiguration fuer akuelle Version. */
public static final Config DEFAULT = new Config("/gdv/xport/config/default.properties");
/** Experimentale Konfiguration zum Testen neuer Features. */
public static final Config EXPERIMENTAL = new Config("/gdv/xport/config/experimental.properties");
/** Eine leere Konfiguration zum Ueberschreiben. */
public static final Config EMPTY = new Config(new Properties());
/** Die Konfiguration fuer die Default-Validierung. */
public static final Config LAX = EMPTY.withProperty("gdv.feld.validate", "lax");
/** Die Konfiguration fuer die strikte Validierung. */
public static final Config STRICT = EMPTY.withProperty("gdv.feld.validate", "strict");
/** Default-Konfiguration fuer 2018. */
public static final Config VUVM2023 = DEFAULT;
/** Default-Konfiguration fuer 2018. */
public static final Config VUVM2018 = DEFAULT.withProperty("gdv.XML-Resource", "VUVM2018.xml");
/** Default-Konfiguration fuer 2015. */
public static final Config VUVM2015 = DEFAULT.withProperty("gdv.XML-Resource", "VUVM2015.xml");
/** Default-Konfiguration fuer 2013. */
public static final Config VUVM2013 = DEFAULT.withProperty("gdv.XML-Resource", "VUVM2013.xml");
/** Default-Konfiguration fuer 2009. */
public static final Config VUVM2009 = DEFAULT.withProperty("gdv.XML-Resource", "VUVM2009.xml");
private final Properties properties;
private final Map, Feld.Validator> defaultValidators = new HashMap<>();
public static Config getInstance() {
return instance;
}
/**
* Zum Testen mit einer Standard-Konfiguration.
* Ueber "-Dgdv.config=meine.properties" kann man eine andere
* Resource fuer die Standard-Konfiguration einstellen.
*
* @since 5.3
*/
public Config() {
//this(System.getProperty("gdv.config", "/gdv/xport/config/default.properties"));
this(System.getProperty("gdv.config", "/gdv.properties"));
}
/**
* Moechte man eine andere Konfiguration, kann man hierueber eine
* alternative Resource angeben.
*
* @param resource z.B. "/gdv/xport/config/experimental.properties"
* @since 5.3
*/
public Config (String resource) {
this(loadProperties(resource));
}
private Config(Properties props) {
this.properties = props;
this.defaultValidators.put(Feld.class, new Feld.Validator(this));
this.defaultValidators.put(FeldXml.class, new FeldXml.Validator(this));
this.defaultValidators.put(NumFeld.class, new NumFeld.Validator(this));
this.defaultValidators.put(AlphaNumFeld.class, new AlphaNumFeld.Validator(this));
this.defaultValidators.put(Zeichen.class, new Zeichen.Validator(this));
this.defaultValidators.put(Satznummer.class, new Satznummer.Validator(this));
this.defaultValidators.put(Betrag.class, new Betrag.Validator(this));
this.defaultValidators.put(BetragMitVorzeichen.class, new BetragMitVorzeichen.Validator(this));
this.defaultValidators.put(Datum.class, new Datum.Validator(this));
this.defaultValidators.put(VUNummer.class, new VUNummer.Validator(this));
this.defaultValidators.put(Version.class, new Version.Validator(this));
init(this.defaultValidators, props);
}
private void init(Map, Feld.Validator> validators, Properties props) {
for (String key : props.stringPropertyNames()) {
if (key.startsWith("gdv.validator.")) {
String classname = key.substring(14);
addTo(validators, classname, props.getProperty(key));
}
}
}
private void addTo(Map, Feld.Validator> validators, String classname, String validatorName) {
try {
Class extends Feld> feldClass = (Class extends Feld>) Class.forName(classname);
Class extends Feld.Validator> validatorClass = (Class extends Feld.Validator>) Class.forName(validatorName);
Feld.Validator v = createValidator(validatorClass);
validators.put(feldClass, v);
LOG.info("Validator {} wurde fuer {} registriert.", v, feldClass);
} catch (ReflectiveOperationException ex) {
throw new ConfigException(String.format("Validator '%s' fuer '%s' nicht gefunden", validatorName, classname), ex);
}
}
private Feld.Validator createValidator(Class extends Feld.Validator> validatorClass) throws ReflectiveOperationException {
try {
return validatorClass.getConstructor(Config.class).newInstance(this);
} catch (ReflectiveOperationException ex) {
LOG.debug("Verwende Default-Ctor, da {} keinen Config-Ctor hat.", validatorClass);
LOG.trace("Details:", ex);
return validatorClass.getConstructor().newInstance();
}
}
private static Properties loadProperties(String resource) {
Properties properties = new Properties();
try (InputStream input = getInputStream(resource)) {
if (input == null) {
LOG.info("default.properties werden geladen, da Resource '{}' nicht vorhanden.", resource);
return loadProperties("/gdv/xport/config/default.properties");
}
LOG.info("Properties werden aus '{}' eingelesen.", resource);
properties.load(input);
addGdvSystemProperties(properties);
return properties;
} catch (IOException ex) {
throw new IllegalArgumentException(String.format("'%s' ist fehlerhaft", resource), ex);
}
}
private static InputStream getInputStream(String resource) throws IOException {
try {
URI uri = new URI(resource);
if (uri.getScheme() != null) {
return getInputStream(uri);
}
} catch (URISyntaxException ex) {
LOG.debug("'{}' wird als Resource betrachtet ({}).", resource, ex);
LOG.trace("Details:", ex);
}
return Config.class.getResourceAsStream(resource);
}
private static InputStream getInputStream(URI uri) throws IOException {
String scheme = uri.getScheme().toLowerCase();
switch (scheme) {
case "file":
return Files.newInputStream(new File(uri).toPath());
case "classpath":
return getInputStream(uri.getPath());
default:
throw new UnsupportedOperationException(String.format("Schema '%s' in %s wird noch nicht unterstuetzt", scheme, uri));
}
}
// nur die SystemProperties, die mit "gdv." anfangen, werden uebernommen
private static void addGdvSystemProperties(Properties props) {
for (Map.Entry