Vorhandene Klassen einfach blind eingefügt
Benötigt einige Nacharbeiten, damit es übersetzbar wird.
This commit is contained in:
parent
77ea70f4e6
commit
8d01fd4935
@ -0,0 +1,69 @@
|
||||
package de.neitzel.core.commandline;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* Provides one argument after the other.
|
||||
*/
|
||||
public class ArgumentProvider implements Iterator<String> {
|
||||
|
||||
/**
|
||||
* List of Arguments (from command line)
|
||||
*/
|
||||
private String[] arguments;
|
||||
|
||||
/**
|
||||
* Current element we work on.
|
||||
*/
|
||||
private int current = 0;
|
||||
|
||||
/**
|
||||
* Creates a new instance of ArgumentProvider.
|
||||
* @param arguments List of Arguments.
|
||||
*/
|
||||
public ArgumentProvider(final String[] arguments) {
|
||||
if (arguments == null) {
|
||||
this.arguments = new String[] {};
|
||||
} else {
|
||||
this.arguments = arguments;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if more arguments are available.
|
||||
* @return True if more arguments are available else false.
|
||||
*/
|
||||
public boolean hasNext() {
|
||||
return current < arguments.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if count more arguments are available.
|
||||
* @param count Number of arguments we want to get.
|
||||
* @return True if count more arguments are available else false.
|
||||
*/
|
||||
public boolean hasNext(final int count) {
|
||||
return current + count <= arguments.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next token.
|
||||
* @return The next token or null if no more available.
|
||||
*/
|
||||
public String next() {
|
||||
if (!hasNext()) return null;
|
||||
|
||||
String result = arguments[current];
|
||||
current++;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next token without removing it.
|
||||
* @return The next token or null if no more available.
|
||||
*/
|
||||
public String peek() {
|
||||
if (!hasNext()) return null;
|
||||
return arguments[current];
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,75 @@
|
||||
package de.neitzel.core.commandline;
|
||||
|
||||
import lombok.*;
|
||||
import lombok.extern.log4j.Log4j;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* A parameter on the command line.
|
||||
* <br>
|
||||
* Each parameter has to start with either - or /!
|
||||
*/
|
||||
@Slf4j
|
||||
@Builder
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class Parameter {
|
||||
|
||||
/**
|
||||
* Name of the parameter.
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* Min number of values given.
|
||||
*/
|
||||
private int minNumberValues;
|
||||
|
||||
/**
|
||||
* Max number of values given.
|
||||
*/
|
||||
private int maxNumberValues;
|
||||
|
||||
/**
|
||||
* Defines if the parameter can be given multiple times.
|
||||
*/
|
||||
private boolean multipleEntries;
|
||||
|
||||
/**
|
||||
* Short description of the parameter.
|
||||
*/
|
||||
private String shortDescription;
|
||||
|
||||
/**
|
||||
* Long description of the parameter.
|
||||
*/
|
||||
private String longDescription;
|
||||
|
||||
/**
|
||||
* Callback wenn der Parameter gefunden wurde.
|
||||
*/
|
||||
private Consumer<List<String>> callback;
|
||||
|
||||
/**
|
||||
* Determines if this Element is the parameter for help.
|
||||
*/
|
||||
private boolean isHelpCommand;
|
||||
|
||||
/**
|
||||
* Determines if this Parameter is the default parameter.
|
||||
* <br>
|
||||
* A default parameter must take at least one additional value.
|
||||
*/
|
||||
private boolean isDefaultParameter;
|
||||
|
||||
/**
|
||||
* List of aliases.
|
||||
*/
|
||||
@Singular("alias")
|
||||
private List<String> aliasList;
|
||||
}
|
||||
145
core/src/main/java/de/neitzel/core/commandline/Parser.java
Normal file
145
core/src/main/java/de/neitzel/core/commandline/Parser.java
Normal file
@ -0,0 +1,145 @@
|
||||
package de.neitzel.core.commandline;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A parser of the CommandLine.
|
||||
* <br>
|
||||
* Parameter are defined. Each parameter will start with either - or /.
|
||||
*/
|
||||
@Slf4j
|
||||
public class Parser {
|
||||
|
||||
/**
|
||||
* Parameters known by the CommandLineParser.
|
||||
*/
|
||||
private Map<String, Parameter> parameters = new HashMap<>();
|
||||
|
||||
/**
|
||||
* The default parameter.
|
||||
*/
|
||||
private Parameter defaultParameter = null;
|
||||
|
||||
/**
|
||||
* Adds a parameter to the list of known parameters.
|
||||
* @param parameter
|
||||
*/
|
||||
public void addParameter(final Parameter parameter) {
|
||||
// Add by name
|
||||
parameters.put(parameter.getName().toLowerCase(), parameter);
|
||||
|
||||
// Add for all aliases
|
||||
for (String alias: parameter.getAliasList()) {
|
||||
parameters.put(alias.toLowerCase(), parameter);
|
||||
}
|
||||
|
||||
// Set help Callback for help command.
|
||||
if (parameter.isHelpCommand())
|
||||
parameter.setCallback(this::helpCommandCallback);
|
||||
|
||||
if (parameter.isDefaultParameter()) {
|
||||
if (parameter.getMinNumberValues() == 0 && parameter.getMaxNumberValues() == 0)
|
||||
throw new IllegalArgumentException("Default Parameter must accept values!");
|
||||
|
||||
defaultParameter = parameter;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if param is a parameter.
|
||||
* <br>
|
||||
* - When the parameter is known as a parameter, then it is true.
|
||||
* - Everything that starts with a - must be a known parameter -> false
|
||||
* - Parameter is not known and does not start with a -? -> Default parameter if available.
|
||||
* @param param Parameter in lower case to check.
|
||||
* @return true if it is either a known parameter or an argument for the default parameter.
|
||||
*/
|
||||
protected boolean isParameter(final String param) {
|
||||
if (parameters.containsKey(param)) return true;
|
||||
if (param.startsWith("-")) return false;
|
||||
return defaultParameter != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given commandline arguments.
|
||||
* @param args Commandline Arguments to parse.
|
||||
*/
|
||||
public void parse(final String[] args) {
|
||||
ArgumentProvider provider = new ArgumentProvider(args);
|
||||
while (provider.hasNext()) {
|
||||
log.debug("Parsing argument: " + provider.peek());
|
||||
|
||||
// Peek to see the next parameter.
|
||||
String next = provider.peek().toLowerCase();
|
||||
if (!isParameter(next)) {
|
||||
log.error("Unknown Parameter: " + next);
|
||||
throw new IllegalArgumentException("Unknown argument: " + next);
|
||||
}
|
||||
|
||||
Parameter parameter = parameters.get(next);
|
||||
if (parameter == null) {
|
||||
parameter = defaultParameter;
|
||||
} else {
|
||||
provider.next();
|
||||
}
|
||||
|
||||
if (!provider.hasNext(parameter.getMinNumberValues())) {
|
||||
String message = "Parameter " + next + " requires " + parameter.getMinNumberValues() + " more elements!";
|
||||
log.error(message);
|
||||
throw new IllegalArgumentException(message);
|
||||
}
|
||||
|
||||
parameter.getCallback().accept(getOptions(provider, parameter.getMinNumberValues(), parameter.getMaxNumberValues()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the given optional data of a parameter-
|
||||
* @param provider Provider of token.
|
||||
* @param min Minimum number of elements to get.
|
||||
* @param max Maximum number of elements to get.
|
||||
* @return List of token of the Parameter.
|
||||
*/
|
||||
private List<String> getOptions(ArgumentProvider provider, int min, int max) {
|
||||
if (max < min) max = min;
|
||||
List<String> result = new ArrayList<>();
|
||||
|
||||
int current = 0;
|
||||
while (current < max && provider.hasNext()) {
|
||||
if (current < min || !parameters.containsKey(provider.peek())) {
|
||||
result.add(provider.next());
|
||||
current++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for help command.
|
||||
* @param arguments null for general help or name of a command.
|
||||
*/
|
||||
public void helpCommandCallback(final List<String> arguments) {
|
||||
if (arguments == null || arguments.size() == 0) {
|
||||
System.out.println("Moegliche Parameter der Applikation:");
|
||||
parameters.values().stream()
|
||||
.distinct()
|
||||
.sorted(Comparator.comparing(Parameter::getName))
|
||||
.forEach(p -> System.out.println(p.getShortDescription() ));
|
||||
} else {
|
||||
Parameter parameter = null;
|
||||
if (parameters.containsKey(arguments.get(0))) parameter = parameters.get(arguments.get(0));
|
||||
if (parameters.containsKey("-" + arguments.get(0))) parameter = parameters.get("-" + arguments.get(0));
|
||||
|
||||
if (parameter == null) {
|
||||
System.out.println("Unbekannter Parameter: " + arguments.get(0));
|
||||
} else {
|
||||
System.out.println(parameter.getLongDescription());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
221
core/src/main/java/de/neitzel/core/config/Configuration.java
Normal file
221
core/src/main/java/de/neitzel/core/config/Configuration.java
Normal file
@ -0,0 +1,221 @@
|
||||
package de.neitzel.core.config;
|
||||
|
||||
import de.neitzel.core.util.FileUtils;
|
||||
import de.neitzel.core.util.Strings;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Base class for a simple configuration.
|
||||
*/
|
||||
@Slf4j
|
||||
public class Configuration {
|
||||
|
||||
/**
|
||||
* Properties with configuration data.
|
||||
*/
|
||||
private Properties properties = new Properties();
|
||||
|
||||
/**
|
||||
* Gets a boolean property
|
||||
* @param defaultValue Default value to return if key is not present.
|
||||
* @param key Key of the property to get.
|
||||
* @return The value of the property if it exists or the default value.
|
||||
*/
|
||||
protected boolean getBooleanProperty(final String key, final boolean defaultValue) {
|
||||
if (!properties.containsKey(key)) return defaultValue;
|
||||
return getStringProperty(key, defaultValue ? "ja": "nein").equalsIgnoreCase("ja") || properties.getProperty(key).equalsIgnoreCase("true");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a String property
|
||||
* @param key Key of the property to query.
|
||||
* @param defaultValue Default value to return if property not available.
|
||||
* @return The property if it exists, else the default value.
|
||||
*/
|
||||
protected String getStringProperty(final String key, final String defaultValue) {
|
||||
if (!properties.containsKey(key)) return defaultValue;
|
||||
return properties.getProperty(key).trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a String property with all environment variables replaced
|
||||
* <p>
|
||||
* Environment variable can be included with ${variable name}.
|
||||
* </p>
|
||||
* @param key Key of the property to query.
|
||||
* @param defaultValue Default value to return if property not available.
|
||||
* @return The property if it exists, else the default value.
|
||||
*/
|
||||
protected String getStringPropertyWithEnv(final String key, final String defaultValue) {
|
||||
String result = getStringProperty(key, defaultValue);
|
||||
return Strings.expandEnvironmentVariables(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a String property without quotes.
|
||||
* <p>
|
||||
* If the value is put in quotes, then the quote signs are replaced.
|
||||
* </p>
|
||||
* @param key Key of the property to query.
|
||||
* @param defaultValue Default value to return if property not available.
|
||||
* @return The property if it exists, else the default value (without leading/ending quote signs).
|
||||
*/
|
||||
protected String getStringPropertyWithoutQuotes(final String key, final String defaultValue) {
|
||||
return Strings.removeQuotes(getStringProperty(key, defaultValue));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a String property without quotes.
|
||||
* <p>
|
||||
* If the value is put in quotes, then the quote signs are replaced.
|
||||
* </p>
|
||||
* @param key Key of the property to query.
|
||||
* @param defaultValue Default value to return if property not available.
|
||||
* @return The property if it exists, else the default value (without leading/ending quote signs).
|
||||
*/
|
||||
protected String getStringPropertyWithoutQuotesWithEnv(final String key, final String defaultValue) {
|
||||
String result = getStringPropertyWithoutQuotes(key, defaultValue);
|
||||
return Strings.expandEnvironmentVariables(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an Integer property.
|
||||
* <br>
|
||||
* Supports null as value.
|
||||
* @param defaultValue Default value to return if key is not present.
|
||||
* @param key Key of the property to get.
|
||||
* @return The value of the property if it exists or the default value.
|
||||
*/
|
||||
protected Integer getIntegerProperty(final String key, final Integer defaultValue) {
|
||||
if (!properties.containsKey(key)) return defaultValue;
|
||||
String value = properties.getProperty(key);
|
||||
return Strings.isNullOrEmpty(value) ? null : Integer.parseInt(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an Integer property.
|
||||
* @param key Key of the property to set.
|
||||
* @param value Value to set.
|
||||
*/
|
||||
protected void setIntegerProperty(final String key, final Integer value) {
|
||||
if (value == null) {
|
||||
properties.setProperty(key, "");
|
||||
} else {
|
||||
properties.setProperty(key, ""+value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the property as LocalDate.
|
||||
* <br>
|
||||
* An null value or an empty String is given as null.
|
||||
* @param key Key of the property.
|
||||
* @param defaultValue default Value.
|
||||
* @param formatString Format String to use.
|
||||
* @return The LocalDate stored the property or the default value if property unknown or couldn't be parsed.
|
||||
*/
|
||||
protected LocalDate getLocalDateProperty(final String key, final LocalDate defaultValue, final String formatString) {
|
||||
if (!properties.containsKey(key)) return defaultValue;
|
||||
|
||||
String value = properties.getProperty(key);
|
||||
if (value == null || value.isEmpty()) return null;
|
||||
return LocalDate.parse(value, DateTimeFormatter.ofPattern(formatString));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the LocalDate using the provided format String.
|
||||
* <br>
|
||||
* Null is allowed and is stored as empty string.
|
||||
* @param key Key of the property to set.
|
||||
* @param value Value to set.
|
||||
* @param formatString Format string to use.
|
||||
*/
|
||||
protected void setLocalDateProperty(final String key, final LocalDate value, final String formatString) {
|
||||
if (value == null) {
|
||||
setProperty(key, "");
|
||||
} else {
|
||||
setProperty(key, value.format(DateTimeFormatter.ofPattern(formatString)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a property to a new value.
|
||||
* @param key Key of property to set.
|
||||
* @param value New value of property.
|
||||
*/
|
||||
public void setProperty(final String key, final String value) {
|
||||
String newValue = value == null ? "" : value;
|
||||
log.info("Setting a new value for '" + key + "': '" + newValue + "'");
|
||||
properties.setProperty(key, newValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the configuration of the file.
|
||||
*/
|
||||
public void load(final String fileName) {
|
||||
load(fileName, Charset.defaultCharset().name(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the configuration of the file.
|
||||
*/
|
||||
public void load(final String fileName, final String encoding, final boolean acceptUTF8) {
|
||||
log.info("Reading Config: " + fileName + " with encoding: " + encoding + "accepting UTF-8: " + acceptUTF8);
|
||||
File configFile = new File(fileName);
|
||||
|
||||
// Try to get the file next to the jar file if the configFile does not exist.
|
||||
if (!configFile.exists()) {
|
||||
try {
|
||||
String fileAtJar = new File(Configuration.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getParent() + "/" + fileName;
|
||||
configFile = new File(fileAtJar);
|
||||
} catch (URISyntaxException ex) {
|
||||
log.error("Unable to get path of jar file / class.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
// Read the configuration file if it exists.
|
||||
if (configFile.exists()) {
|
||||
log.info("Reading Configuration file. " + configFile.getAbsolutePath());
|
||||
try (InputStreamReader reader = FileUtils.createUniversalFileReader(configFile, encoding, acceptUTF8)) {
|
||||
log.info("Reading the configuration with encoding: " + reader.getEncoding());
|
||||
properties.load(reader);
|
||||
} catch (FileNotFoundException fnfe) {
|
||||
log.error("Configuration file: " + fileName + " not found!", fnfe);
|
||||
} catch (IOException ioe) {
|
||||
log.error("Cannot read config file.", ioe);
|
||||
}
|
||||
} else {
|
||||
log.error("Unable to load config file! Last try: " + configFile.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert the configuration settings of the given config.
|
||||
* @param config Configuration to merge into this instance.
|
||||
*/
|
||||
public void merge(final Configuration config) {
|
||||
for(Map.Entry<Object, Object> entry: config.properties.entrySet()) {
|
||||
properties.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a key from the configuration.
|
||||
* @param key
|
||||
*/
|
||||
public void remove(final String key){
|
||||
if (properties.containsKey(key)) properties.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,76 @@
|
||||
package de.neitzel.core.io;
|
||||
|
||||
import de.neitzel.core.util.FileUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.IllegalCharsetNameException;
|
||||
|
||||
/**
|
||||
* FileReader that converts an UTF-8 file to ISO-8859-15 if required.
|
||||
* <p>
|
||||
* This FileReader checks, if the file to be read is an UTF-8 file.
|
||||
* If an UTF-8 encoding is found, a temporary file will be created with the content
|
||||
* of the original File - just encoded in the new format.
|
||||
* </p>
|
||||
* <p>
|
||||
* This Reader is mainly tested ith ISO-8859-15 and UTF-8. Other formats are not really supported.
|
||||
* </p>
|
||||
*/
|
||||
@Slf4j
|
||||
public class ConvertedEncodingFileReader extends InputStreamReader {
|
||||
|
||||
private static String checkEncoding = "ISO-8859-15";
|
||||
|
||||
private static void setCheckEncoding(final String encoding) {
|
||||
if (Charset.forName(encoding) != null) throw new IllegalCharsetNameException("Encoding " + encoding + " is not supported!");
|
||||
|
||||
checkEncoding = encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ConvertedEncodingFileReader from a given File.
|
||||
* @param file File to convert if required and open reader.
|
||||
* @param targetFormat Target Format to use.
|
||||
* @throws IOException
|
||||
*/
|
||||
public ConvertedEncodingFileReader(final File file, final String targetFormat) throws IOException {
|
||||
super(createTargetFormatInputFileStream(file, targetFormat), targetFormat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ISO8859ConvertedFileReader from a given File.
|
||||
* @param filename File to convert if required and open reader.
|
||||
* @throws IOException
|
||||
*/
|
||||
public ConvertedEncodingFileReader(final String filename, final String targetFormat) throws IOException {
|
||||
this(new File(filename), targetFormat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ISO8859-15 encoded InputFileStream on an file.
|
||||
* <p>
|
||||
* If the file is UTF-8 encoded, then it is converted to a temp file and the temp file will be opened.
|
||||
* </p>
|
||||
* @param file
|
||||
* @return The InputFileStream on the original file or the converted file in case of an UTF-8 file.
|
||||
* @throws IOException
|
||||
*/
|
||||
private static FileInputStream createTargetFormatInputFileStream(final File file, final String targetFormat) throws IOException {
|
||||
if (!file.exists()) {
|
||||
String errorMessage = "File " + file.toString() + " does not exist!";
|
||||
log.error(errorMessage);
|
||||
throw new FileNotFoundException(errorMessage);
|
||||
}
|
||||
|
||||
if (!FileUtils.isUTF8(file, checkEncoding)) {
|
||||
return new FileInputStream(file);
|
||||
} else {
|
||||
File tempFile = File.createTempFile(file.getName(), "tmp");
|
||||
FileUtils.convertTextFile(file, "UTF-8", tempFile, targetFormat);
|
||||
tempFile.deleteOnExit();
|
||||
return new FileInputStream(tempFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package de.neitzel.core.io;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ISO8859EncodingFileReader extends ConvertedEncodingFileReader {
|
||||
|
||||
private static final String TARGET_FORMAT = "ISO-8859-15";
|
||||
|
||||
public ISO8859EncodingFileReader(File file) throws IOException {
|
||||
super(file, TARGET_FORMAT);
|
||||
}
|
||||
|
||||
public ISO8859EncodingFileReader(String filename) throws IOException {
|
||||
super(filename, TARGET_FORMAT);
|
||||
}
|
||||
}
|
||||
75
core/src/main/java/de/neitzel/core/io/StringEncoder.java
Normal file
75
core/src/main/java/de/neitzel/core/io/StringEncoder.java
Normal file
@ -0,0 +1,75 @@
|
||||
package de.neitzel.core.io;
|
||||
|
||||
/**
|
||||
* An encoder for Strings.
|
||||
* <p>
|
||||
* All characters with unicode number less than 32 or greater than 127 or 38 (Ampersend)
|
||||
* will be encoded with &#number; with number as the decimal unicode number.
|
||||
*/
|
||||
public class StringEncoder {
|
||||
|
||||
/**
|
||||
* Decodes the encoded String.
|
||||
* @param data Encoded string.
|
||||
* @return Decoded String.
|
||||
*/
|
||||
public static String decodeData(final String data) {
|
||||
if (data == null) return "";
|
||||
|
||||
String remaining = data;
|
||||
StringBuilder result = new StringBuilder();
|
||||
while (!remaining.isEmpty()) {
|
||||
int indexAmp = remaining.indexOf("&");
|
||||
if (indexAmp == -1) {
|
||||
result.append(remaining);
|
||||
remaining="";
|
||||
} else {
|
||||
// First get the elements till the &
|
||||
if (indexAmp > 0) {
|
||||
result.append(remaining.substring(0, indexAmp));
|
||||
remaining = remaining.substring(indexAmp);
|
||||
}
|
||||
int endSpecial=remaining.indexOf(";");
|
||||
if (endSpecial == -1) throw new IllegalArgumentException("String couldn't be decoded! (" + data + ")");
|
||||
String special = remaining.substring(0, endSpecial+1);
|
||||
remaining = remaining.substring(endSpecial+1);
|
||||
result.append(decodeCharacter(special));
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a single character.
|
||||
* @param data String in the form &#xxx; with xxx a decimal number.
|
||||
* @return The decoded character.
|
||||
*/
|
||||
public static char decodeCharacter(final String data) {
|
||||
if (!data.startsWith("&#")) throw new IllegalArgumentException("Data does not start with &# (" + data + ")");
|
||||
if (!data.endsWith(";")) throw new IllegalArgumentException("Data does not end with ; (" + data + ")");
|
||||
return (char)Integer.parseInt(data.substring(2, data.length()-1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode data to a better String representation.
|
||||
* <p>
|
||||
* All Characters between from ascii 32 to 127 (except 38 / &)
|
||||
* are replaced with a &#code; where code is the number of the character.
|
||||
* @param data String that should be encoded.
|
||||
* @return Encoded String.
|
||||
*/
|
||||
public static String encodeData(final String data) {
|
||||
if (data == null) return "";
|
||||
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (int index=0; index < data.length(); index++) {
|
||||
char character = data.charAt(index);
|
||||
if (character < 32 || character > 127 || character == 38) {
|
||||
result.append("&#" + (int)character + ";");
|
||||
} else {
|
||||
result.append(character);
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
20
core/src/main/java/de/neitzel/core/util/ArrayUtils.java
Normal file
20
core/src/main/java/de/neitzel/core/util/ArrayUtils.java
Normal file
@ -0,0 +1,20 @@
|
||||
package de.neitzel.core.util;
|
||||
|
||||
/**
|
||||
* Utility Class with static methods about arrays.
|
||||
*/
|
||||
public class ArrayUtils {
|
||||
|
||||
/**
|
||||
* Checks if a given char is inside an array of chars.
|
||||
* @param array Array of chars to seach in.
|
||||
* @param ch Character to search.
|
||||
* @return true if character was found, else false.
|
||||
*/
|
||||
public static boolean contains(char[] array, char ch) {
|
||||
for(int index=0; index < array.length; index++) {
|
||||
if (array[index] == ch) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
49
core/src/main/java/de/neitzel/core/util/EnumUtil.java
Normal file
49
core/src/main/java/de/neitzel/core/util/EnumUtil.java
Normal file
@ -0,0 +1,49 @@
|
||||
package de.neitzel.core.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Enumeration Utilities
|
||||
*/
|
||||
public class EnumUtil {
|
||||
/**
|
||||
* Creates a regular expression to match a comma separated list of Flags.
|
||||
* @return Regular expression to match flags.
|
||||
*/
|
||||
public static <T extends Enum<T>> String getFlagRegEx(Class<T> clazz) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
result.append("(|,|\\s");
|
||||
|
||||
for (T flag: clazz.getEnumConstants()) {
|
||||
result.append("|");
|
||||
for(char ch: flag.toString().toUpperCase().toCharArray()) {
|
||||
if (Character.isAlphabetic(ch)) {
|
||||
result.append("[");
|
||||
result.append(ch);
|
||||
result.append(Character.toLowerCase(ch));
|
||||
result.append("]");
|
||||
} else {
|
||||
result.append(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
result.append(")*");
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a list of comma separated flags into a List of RequestFlags.
|
||||
* @param flags String with comma separated flags.
|
||||
* @return List of RequestFlags.
|
||||
*/
|
||||
public static <T extends Enum<T>> List<T> parseFlags(final Class<T> clazz, final String flags) {
|
||||
List<T> result = new ArrayList<>();
|
||||
if (flags != null) {
|
||||
for (String flag: flags.split("[,\\s]")) {
|
||||
if (!flag.isEmpty()) result.add(T.valueOf(clazz, flag.toUpperCase()));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
246
core/src/main/java/de/neitzel/core/util/FileUtils.java
Normal file
246
core/src/main/java/de/neitzel/core/util/FileUtils.java
Normal file
@ -0,0 +1,246 @@
|
||||
package de.neitzel.core.util;
|
||||
|
||||
import lombok.extern.log4j.Log4j;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Utility Methods regarding files.
|
||||
*/
|
||||
@Slf4j
|
||||
public class FileUtils {
|
||||
|
||||
/**
|
||||
* Date/Time format to add to request files.
|
||||
*/
|
||||
public static final SimpleDateFormat DEBUG_FILE_TIMESTAMP_FORMAT = new SimpleDateFormat("yyyy-MM-dd_HH_mm_ss_SSS");
|
||||
|
||||
/**
|
||||
* Default encoding used to check the File
|
||||
*/
|
||||
public static final String DEFAULT_CHECK_ENCODING = "ISO-8859-15";
|
||||
|
||||
/**
|
||||
* Default Buffer size.
|
||||
*/
|
||||
public static final int BUFFER_SIZE = 1024;
|
||||
|
||||
/**
|
||||
* Checks if a File is UTF-8 encoded.
|
||||
* <p>
|
||||
* This method checks a file for
|
||||
* - first 3 bytes for UTF-8 BOM (0xEF 0xBB 0xBF)
|
||||
* - Existence of 0xC2 / 0xC3 character.
|
||||
* </p>
|
||||
* @param file File to check.
|
||||
* @param checkEncoding Encoding to use for the check, e.g. ISO-8859-15.
|
||||
* @return true if an UTF-8 file is found, else false.
|
||||
* @throws IOException IOException is thrown if the file could not be read.
|
||||
*/
|
||||
public static boolean isUTF8(final File file, final String checkEncoding) throws IOException {
|
||||
|
||||
if (hasUTF8BOM(file)) return true;
|
||||
|
||||
int BUFFER_SIZE = 1024;
|
||||
char[] buffer = new char[BUFFER_SIZE];
|
||||
|
||||
try (InputStreamReader reader = new InputStreamReader(new FileInputStream(file), checkEncoding)) {
|
||||
|
||||
while (reader.read(buffer, 0, BUFFER_SIZE) > 0) {
|
||||
|
||||
if (
|
||||
(ArrayUtils.contains(buffer, (char) 0x00C2)) // Part of UTF-8 Characters 0xC2 0xZZ
|
||||
|| (ArrayUtils.contains(buffer, (char) 0x00C3))) { // Part of UTF-8 Characters 0xC3 0xZZ
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
} catch (IOException ex) {
|
||||
log.error("Exception while reading file.", ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the File has a UTF-8 BOM.
|
||||
* <p>
|
||||
* This method checks a file for
|
||||
* - first 3 bytes for UTF-8 BOM (0xEF 0xBB 0xBF)
|
||||
* - Existence of 0xC2 / 0xC3 character.
|
||||
* </p>
|
||||
* @param file File to check.
|
||||
* @return true if an UTF-8 BOM Header was found.
|
||||
* @throws IOException IOException is thrown if the file could not be read.
|
||||
*/
|
||||
public static boolean hasUTF8BOM(final File file) throws IOException {
|
||||
try (InputStreamReader reader = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)) {
|
||||
return reader.read() == 0xFEFF;
|
||||
} catch (IOException ex) {
|
||||
log.error("Exception while reading file.", ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a File is UTF-8 encoded.
|
||||
* <p>
|
||||
* This method checks a file for
|
||||
* - first 3 bytes for UTF-8 BOM (0xEF 0xBB 0xBF)
|
||||
* - Existence of 0xC2 / 0xC3 character.
|
||||
* </p>
|
||||
* @param file File to check.
|
||||
* @return true if an UTF-8 file is found, else false.
|
||||
* @throws IOException IOException is thrown if the file could not be read.
|
||||
*/
|
||||
public static boolean isUTF8(final File file) throws IOException {
|
||||
return isUTF8(file, DEFAULT_CHECK_ENCODING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given Textfile inFile to the outFile using the given encodings.
|
||||
* @param inFile File to read as UTF-8.
|
||||
* @param sourceFormat Format of the source file.
|
||||
* @param outFile File to write with ISO-8859-15 format.
|
||||
* @param targetFormat Format of the target file.
|
||||
* @throws IOException Thrown when files couldn't be read / written.
|
||||
*/
|
||||
public static void convertTextFile(final File inFile, final String sourceFormat, final File outFile, final String targetFormat) throws IOException {
|
||||
char[] buffer = new char[BUFFER_SIZE];
|
||||
|
||||
int charsRead, startIndex;
|
||||
boolean first = true;
|
||||
try (InputStreamReader reader = new InputStreamReader(new FileInputStream(inFile), sourceFormat);
|
||||
OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(outFile), targetFormat)) {
|
||||
|
||||
while ((charsRead = reader.read(buffer, 0, BUFFER_SIZE)) > 0) {
|
||||
startIndex = 0;
|
||||
|
||||
if (first) {
|
||||
// Check UTF-8 BOM
|
||||
if (buffer[0] == 0xFEFF) {
|
||||
log.info("BOM found!");
|
||||
startIndex = 1;
|
||||
}
|
||||
|
||||
first = false;
|
||||
}
|
||||
|
||||
writer.write(buffer, startIndex, charsRead - startIndex);
|
||||
}
|
||||
|
||||
} catch (IOException ex) {
|
||||
log.error("Exception when converting Textfile.", ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new InputStreamReader with the given format or UTF-8 if an UTF-8 file was recognized.
|
||||
* @param filename Name of file to read.
|
||||
* @return An InputStreamReader
|
||||
*/
|
||||
public static InputStreamReader createUniversalFileReader(final String filename) throws IOException {
|
||||
return createUniversalFileReader(new File(filename));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new InputStreamReader with the given format or UTF-8 if an UTF-8 file was recognized.
|
||||
* @param filename Name of file to read.
|
||||
* @param expectedFormat Expected format e.g. ISO-8859-15
|
||||
* @return An InputStreamReader
|
||||
*/
|
||||
public static InputStreamReader createUniversalFileReader(final String filename, final String expectedFormat) throws IOException {
|
||||
return createUniversalFileReader(new File(filename), expectedFormat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new InputStreamReader with the given format or UTF-8 if an UTF-8 file was recognized.
|
||||
* @param file File to read.
|
||||
* @return An InputStreamReader
|
||||
*/
|
||||
public static InputStreamReader createUniversalFileReader(final File file) throws IOException {
|
||||
return createUniversalFileReader(file, DEFAULT_CHECK_ENCODING, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new InputStreamReader with the given format or UTF-8 if an UTF-8 file was recognized.
|
||||
* @param file File to read.
|
||||
* @param expectedFormat Expected format e.g. ISO-8859-15
|
||||
* @return An InputStreamReader
|
||||
*/
|
||||
public static InputStreamReader createUniversalFileReader(final File file, final String expectedFormat) throws IOException {
|
||||
return createUniversalFileReader(file, expectedFormat, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new InputStreamReader with the given format or UTF-8 if an UTF-8 file was recognized.
|
||||
* @param file File to read.
|
||||
* @param expectedFormat Expected format e.g. ISO-8859-15
|
||||
* @return An InputStreamReader
|
||||
*/
|
||||
public static InputStreamReader createUniversalFileReader(final File file, final String expectedFormat, final boolean acceptUTF8) throws IOException {
|
||||
String encoding = acceptUTF8 && isUTF8(file, expectedFormat)
|
||||
? "UTF-8"
|
||||
: expectedFormat;
|
||||
|
||||
boolean skipBOM = encoding.equals("UTF-8") && hasUTF8BOM(file);
|
||||
|
||||
InputStreamReader result = new InputStreamReader(new FileInputStream(file), encoding);
|
||||
if (skipBOM) {
|
||||
int BOM = result.read();
|
||||
if (BOM != 0xFEFF) log.error ("Skipping BOM but value not 0xFEFF!");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the parent directory of a file name.
|
||||
* @param filename Name of file.
|
||||
* @return Parent folder.
|
||||
*/
|
||||
public static String getParentDirectory(final String filename) {
|
||||
File file = new File(filename);
|
||||
return file.getParent() != null ? file.getParent() : ".";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the core name of the file without path.
|
||||
* @param filename Filename with path.
|
||||
* @return Filename without path.
|
||||
*/
|
||||
public static String getFilename(final String filename) {
|
||||
File file = new File(filename);
|
||||
return file.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the content of a file (With the correct encoding!).
|
||||
* @param filename Name of file to read.
|
||||
* @return Content of the file or null in case of an error.
|
||||
* @throws IOException Throes an IOException if the file cannot be read.
|
||||
*/
|
||||
public static String readFileContent(final String filename) throws IOException {
|
||||
try (BufferedReader reader = new BufferedReader(createUniversalFileReader(filename))) {
|
||||
return reader.lines().collect(Collectors.joining(System.lineSeparator()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the content given to a file.
|
||||
* @param path Path of the file to write.
|
||||
* @param content Content to write.
|
||||
* @throws IOException Thrown if the file could not be written.
|
||||
*/
|
||||
public static void writeFile(final Path path, final String content) throws IOException {
|
||||
try (BufferedWriter writer = new BufferedWriter(new FileWriter(path.toFile()))) {
|
||||
writer.write(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
package de.neitzel.core.util;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class RegionalizationMessage {
|
||||
|
||||
/**
|
||||
* Resource Bundle to use for operations.
|
||||
*/
|
||||
private ResourceBundle res;
|
||||
|
||||
/**
|
||||
* Creates a new instance of RegionalizationMessage.
|
||||
* @param source Source of messages.
|
||||
*/
|
||||
public RegionalizationMessage(final String source) {
|
||||
res = ResourceBundle.getBundle(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of RegionalizationMessage.
|
||||
* @param source Source of messages.
|
||||
* @param locale Locale to use.
|
||||
*/
|
||||
public RegionalizationMessage(final String source, final Locale locale) {
|
||||
res = ResourceBundle.getBundle(source, locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Message behind a key.
|
||||
* @param key Key to look up.
|
||||
* @return Message or null.
|
||||
*/
|
||||
public String getMessage(final String key) {
|
||||
if (!res.containsKey(key)) return null;
|
||||
return res.getString(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Message behind a key.
|
||||
* @param key Key to look up.
|
||||
* @param defaultMessage Default message to use if message is not available.
|
||||
* @return Message from resource or default Message.
|
||||
*/
|
||||
public String getMessage(final String key, final String defaultMessage) {
|
||||
if (res.containsKey(key))
|
||||
return res.getString(key);
|
||||
|
||||
return defaultMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a formatted message.
|
||||
* @param key key to look up message.
|
||||
* @param defaultMessage Default message to use if message couldn't be loaded.
|
||||
* @param params parameter to format the message.
|
||||
* @return Formatted message.
|
||||
*/
|
||||
public String getFormattedMessage(final String key, final String defaultMessage, final Object... params) {
|
||||
MessageFormat format = new MessageFormat(getMessage(key, defaultMessage));
|
||||
return format.format(params);
|
||||
}
|
||||
}
|
||||
109
core/src/main/java/de/neitzel/core/util/Strings.java
Normal file
109
core/src/main/java/de/neitzel/core/util/Strings.java
Normal file
@ -0,0 +1,109 @@
|
||||
package de.neitzel.core.util;
|
||||
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Utility Methods for Strings
|
||||
*/
|
||||
public class Strings {
|
||||
/**
|
||||
* Environment variables of the system.
|
||||
*/
|
||||
private static Map<String, String> environmentVariables = System.getenv();
|
||||
|
||||
/**
|
||||
* Expands environment Variables inside a string.
|
||||
* <p>
|
||||
* The environment variables should be given as ${variable}.
|
||||
* </p>
|
||||
* <p>
|
||||
* Backslash inside variable values are replaced with slashes to avoid that they are seen as escape character.
|
||||
* This makes the use for paths on windows possible but reduces the use with non paths in which you need a backslash.
|
||||
* </p>
|
||||
* @param text Test in which environment variables should be expanded.
|
||||
* @return String with all environment variables expanded.
|
||||
*/
|
||||
public static String expandEnvironmentVariables(String text) {
|
||||
if (text == null) return null;
|
||||
for (Map.Entry<String, String> entry : environmentVariables.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
String value = entry.getValue().replace('\\', '/');
|
||||
text = text.replaceAll("\\$\\{" + key + "\\}", value);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given String is null or empty.
|
||||
* @param string String to check.
|
||||
* @return true if given String is null or empty.
|
||||
*/
|
||||
public static boolean isNullOrEmpty(final String string) {
|
||||
return (string == null || string.length()==0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a leading / ending quote if there.
|
||||
* @param value String to remove the quotes.
|
||||
* @return Parameter string if it does not start / end with a quote, else string without leading/ending quote.
|
||||
*/
|
||||
public static String removeQuotes(final String value) {
|
||||
String trimmedValue = value.trim();
|
||||
if (trimmedValue.length() > 1 && trimmedValue.startsWith("\"") && trimmedValue.endsWith("\""))
|
||||
return trimmedValue.substring(1, trimmedValue.length()-1);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters a given String and removes all illegal characters.
|
||||
* @param value String value to filter all illegal characters from.
|
||||
* @param illegalCharacters String with all Illegal Characters to filter out.
|
||||
* @param replacement String to replace illegal characters with.
|
||||
* @param combine Should multiple illegal characters that are together be replaced with one replacement string only?
|
||||
* @return A new string where all illegal characters are replaced with the replacement string.
|
||||
*/
|
||||
public static String replaceIllegalCharacters(final String value, final String illegalCharacters, final String replacement, final boolean combine) {
|
||||
String replacementRegex = "[" + illegalCharacters + "]" + (combine ? "+" : "");
|
||||
return value.replaceAll(replacementRegex, replacement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters a given String and removes all illegal characters.
|
||||
* <p>
|
||||
* All characters, that are not inside allowedCharacters, are illegal characters.
|
||||
* </p>
|
||||
* @param value String value to filter all illegal characters from.
|
||||
* @param allowedCharacters String with all allowed Characters to filter out.
|
||||
* @param replacement String to replace illegal characters with.
|
||||
* @param combine Should multiple illegal characters that are together be replaced with one replacement string only?
|
||||
* @return A new string where all illegal characters are replaced with the replacement string.
|
||||
*/
|
||||
public static String replaceNonAllowedCharacters(final String value, final String allowedCharacters, final String replacement, final boolean combine) {
|
||||
String replacementRegex = "[^" + allowedCharacters + "]" + (combine ? "+" : "");
|
||||
return value.replaceAll(replacementRegex, replacement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next Element which follows to the current element.
|
||||
* @param element to get the precessor.
|
||||
* @return The next element after this one.
|
||||
*/
|
||||
public static String increment(@NonNull final String element) {
|
||||
if (element.isEmpty()) return "1";
|
||||
|
||||
String firstPart = element.substring(0, element.length()-1);
|
||||
char lastChar = element.charAt(element.length()-1);
|
||||
if (lastChar == '9') return firstPart + 'A';
|
||||
if (lastChar == 'Z') return increment(firstPart) + '0';
|
||||
return firstPart + (char)(lastChar+1);
|
||||
}
|
||||
|
||||
public static String limitCharNumber(final String original, final int maxLength) {
|
||||
if (original == null || original.length() <= maxLength) return original;
|
||||
|
||||
return original.substring(0, maxLength);
|
||||
}
|
||||
}
|
||||
203
core/src/main/java/de/neitzel/core/util/XmlUtils.java
Normal file
203
core/src/main/java/de/neitzel/core/util/XmlUtils.java
Normal file
@ -0,0 +1,203 @@
|
||||
package de.neitzel.core.util;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.extern.log4j.Log4j;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.transform.*;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Converter with helper functions to format XML.
|
||||
*/
|
||||
@Slf4j
|
||||
public class XmlUtils {
|
||||
|
||||
/**
|
||||
* DateTimeFormatter instance to format a date for XML use (xs:date type).
|
||||
*/
|
||||
public static final DateTimeFormatter XML_DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||
|
||||
/**
|
||||
* Creates a new XML element to be used inside a document.
|
||||
*
|
||||
* @param doc XML Document to use.
|
||||
* @param name Name of the Element.
|
||||
* @return Created Element.
|
||||
*/
|
||||
public static Element createElement(final Document doc, final String name) {
|
||||
log.debug("Creating a new element " + name);
|
||||
return doc.createElement(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new XML element with text value to be used inside a document.
|
||||
*
|
||||
* @param doc XML Document to use.
|
||||
* @param name Name of the Element.
|
||||
* @param value Value of the Text Node.
|
||||
* @return Created Element.
|
||||
*/
|
||||
public static Element createElement(final Document doc, final String name, final String value) {
|
||||
log.debug("Creating a new element " + name + " with value: " + value);
|
||||
Element element = doc.createElement(name);
|
||||
|
||||
Node content = doc.createTextNode(value != null ? value : "");
|
||||
element.appendChild(content);
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new XML element with date value to be used inside a document.
|
||||
*
|
||||
* @param doc XML Document to use.
|
||||
* @param name Name of the Element.
|
||||
* @param value Date to insert into node.
|
||||
* @return Created Element.
|
||||
*/
|
||||
public static Element createElement(final Document doc, final String name, final Date value) {
|
||||
return createElement(doc, name, XML_DATE_FORMATTER.format(value.toInstant()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new XML element with integer value to be used inside a document.
|
||||
*
|
||||
* @param doc XML Document to use.
|
||||
* @param name Name of the Element.
|
||||
* @param value Value of the Integer Node.
|
||||
* @return Created Element.
|
||||
*/
|
||||
public static Element createElement(final Document doc, final String name, final Integer value) {
|
||||
log.debug("Creating a new element " + name + " with value: " + value);
|
||||
Element element = doc.createElement(name);
|
||||
|
||||
Node content = doc.createTextNode(value != null ? ""+value : "");
|
||||
element.appendChild(content);
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new XML element to be used inside a document and adds it to the parent.
|
||||
*
|
||||
* @param doc XML Document to use.
|
||||
* @param name Name of the Element.
|
||||
* @param parent Parent for the Element.
|
||||
* @return Created Element.
|
||||
*/
|
||||
public static Element createAndInsertElement(final Document doc, final String name, @NonNull final Element parent) {
|
||||
log.debug("Creating a new element " + name + " and adding it to a parent.");
|
||||
Element element = createElement(doc, name);
|
||||
parent.appendChild(element);
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new XML element with text value And adds it to the parent.
|
||||
*
|
||||
* @param name Name of the Element.
|
||||
* @param value Value of the Text Node.
|
||||
* @param parent Parent for the Element.
|
||||
* @return Created Element.
|
||||
*/
|
||||
public static Element createAndInsertElement(final Document doc, final String name, final String value, @NonNull final Element parent) {
|
||||
log.debug("Creating a new element " + name + " with value: " + value + " and adding it to a parent.");
|
||||
Element element = createElement(doc, name, value);
|
||||
parent.appendChild(element);
|
||||
return element;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Formats the XML from a given String with XML content.
|
||||
*
|
||||
* @param xmlStream String with XML content.
|
||||
* @return Formated XML content or original content in case of an error.
|
||||
*/
|
||||
public static String format(final String xmlStream) {
|
||||
log.debug("formatXML");
|
||||
|
||||
try {
|
||||
Source xmlInput = new StreamSource(new StringReader(xmlStream));
|
||||
StringWriter stringWriter = new StringWriter();
|
||||
StreamResult xmlOutput = new StreamResult(stringWriter);
|
||||
|
||||
TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
||||
transformerFactory.setAttribute("indent-number", "4");
|
||||
|
||||
Transformer transformer = transformerFactory.newTransformer();
|
||||
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||
transformer.transform(xmlInput, xmlOutput);
|
||||
|
||||
return xmlOutput.getWriter().toString();
|
||||
}
|
||||
catch(TransformerException e) {
|
||||
log.error("Error in XML: " + e.getMessage() + "\n"+xmlStream, e);
|
||||
}
|
||||
|
||||
return xmlStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the XML from a given XML Document.
|
||||
*
|
||||
* @param doc XML Document to format.
|
||||
* @return Formated XML content.
|
||||
*/
|
||||
public static String format(final Document doc) {
|
||||
try {
|
||||
TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
||||
transformerFactory.setAttribute("indent-number", "4");
|
||||
Transformer transformer = transformerFactory.newTransformer();
|
||||
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||
transformer.setOutputProperty(OutputKeys.STANDALONE, "yes");
|
||||
transformer.setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1");
|
||||
StringWriter stringWriter = new StringWriter();
|
||||
|
||||
Source source = new DOMSource(doc);
|
||||
Result result = new StreamResult(stringWriter);
|
||||
transformer.transform(source, result);
|
||||
|
||||
String xmlString = stringWriter.toString();
|
||||
log.info("MO Request: " + xmlString);
|
||||
return xmlString;
|
||||
}
|
||||
catch(TransformerException e) {
|
||||
log.error("Error in XML Transformation: " + e.getMessage(), e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given xml string is valid XML
|
||||
* @param xml XML String.
|
||||
* @return true if xml is valid.
|
||||
*/
|
||||
public static boolean checkXml(final String xml) {
|
||||
try {
|
||||
InputStream stream = new ByteArrayInputStream(xml.getBytes());
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder docBuilder = dbf.newDocumentBuilder();
|
||||
Document document = docBuilder.parse(stream);
|
||||
return document != null;
|
||||
} catch (Exception ex) {
|
||||
log.warn("Exception when validating xml.", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
54
log4j/pom.xml
Normal file
54
log4j/pom.xml
Normal file
@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>de.neitzel.lib</groupId>
|
||||
<artifactId>neitzellib</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>log4j</artifactId>
|
||||
|
||||
<properties>
|
||||
<!-- Application Properties -->
|
||||
<link.name>${project.artifactId}</link.name>
|
||||
<launcher>${project.artifactId}</launcher>
|
||||
<appName>${project.artifactId}</appName>
|
||||
<jar.filename>${project.artifactId}-${project.version}</jar.filename>
|
||||
|
||||
<!-- Dependency Versions -->
|
||||
<log4j.version>1.2.17</log4j.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>${log4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>apache-log4j-extras</artifactId>
|
||||
<version>${log4j.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>${jar.filename}</finalName>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.github.spotbugs</groupId>
|
||||
<artifactId>spotbugs-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-pmd-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
75
log4j/src/main/java/de/neitzel/log4j/Log4jUtils.java
Normal file
75
log4j/src/main/java/de/neitzel/log4j/Log4jUtils.java
Normal file
@ -0,0 +1,75 @@
|
||||
package de.neitzel.log4j;
|
||||
|
||||
import org.apache.log4j.PropertyConfigurator;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
/**
|
||||
* Adds Utility Methods for log4j.
|
||||
*/
|
||||
public class Log4jUtils {
|
||||
|
||||
/**
|
||||
* Default Logfile that should be read.
|
||||
* Must be a relative path that is checked from the current directory and also from the location of the jar file.
|
||||
*/
|
||||
public static final String DEFAULT_LOG4J_LOGFILE = "./log4j.properties";
|
||||
|
||||
/**
|
||||
* Resource to use when no file is found.
|
||||
*/
|
||||
public static final String DEFAULT_LOG4J_RESOURCE = "/log4j.default.properties";
|
||||
|
||||
/**
|
||||
* Checks if a log4j config file was set on command line with -Dlog4j.configuration
|
||||
* @return true if log4j.configuration was set.
|
||||
*/
|
||||
public static boolean isLog4jConfigFileSet() {
|
||||
return System.getProperty("log4j.configuration") != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the default configurations if no config file was set.
|
||||
*/
|
||||
public static void setLog4jConfiguration() {
|
||||
setLog4jConfiguration(DEFAULT_LOG4J_LOGFILE, DEFAULT_LOG4J_RESOURCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the file with path relative to the jar file.
|
||||
* @param log4jConfigFile log4j config file.
|
||||
* @return Path if possible or null.
|
||||
*/
|
||||
public static String getLog4jLogfileAtJar(final String log4jConfigFile) {
|
||||
try {
|
||||
return new File(Log4jUtils.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getParent() + "/" + log4jConfigFile;
|
||||
} catch (URISyntaxException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the default configurations if no config file was set.
|
||||
* <p>
|
||||
* A log4j configuration can be set using -Dlog4j.configuration. If no configuration was set,
|
||||
* we look for the log4jConfigFile. If it does not exist, we read the defaultResource.
|
||||
* </p>
|
||||
* @param log4jConfigFile Default file to look for.
|
||||
* @param defaultResource Resource path to use if config file wasn't found.
|
||||
*/
|
||||
public static void setLog4jConfiguration(final String log4jConfigFile, final String defaultResource) {
|
||||
if (isLog4jConfigFileSet()) return;
|
||||
|
||||
String fileAtJar = getLog4jLogfileAtJar(log4jConfigFile);
|
||||
|
||||
if (new File(log4jConfigFile).exists()) {
|
||||
PropertyConfigurator.configure(log4jConfigFile);
|
||||
} else if (fileAtJar != null && new File(fileAtJar).exists()) {
|
||||
System.out.println("Nutze Log4J Konfiguration bei jar File: " + fileAtJar);
|
||||
PropertyConfigurator.configure(fileAtJar);
|
||||
}else {
|
||||
PropertyConfigurator.configure(Log4jUtils.class.getResource(defaultResource));
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user