Skip to content
Snippets Groups Projects
Commit b19a3d47 authored by Leonard Kupper's avatar Leonard Kupper
Browse files

Restructure config parser to handle internal recursive calls for include files.

parent b034a9a5
No related branches found
No related tags found
1 merge request!19Feat/configparser update 29
......@@ -19,11 +19,10 @@ import java.util.Set;
public abstract class ConfigurationParser {
private FileInputStream mInput;
private ConfigurationValidator mValidator;
private Printer mPrinter;
private Map<String, Format> mFormats = new HashMap<>();
private String mConfigFilePath;
private File mCurrentConfigFile;
private List<PrinterProperty> mPrinterProperties = new ArrayList<>();
private Map<String, List<FormatProperty>> mFormatProperties = new HashMap<>();
private Printer mDefaultPrinter;
......@@ -35,14 +34,15 @@ public abstract class ConfigurationParser {
/**
* Internal algorithm used for parsing of the configuration file.
* Implement this method by parsing information from the configuration file (see {@link #getInput()}), optionally validating it (see {@link ConfigurationValidator}),
* Implement this method by parsing information from the given input stream, optionally validating it (see {@link ConfigurationValidator}),
* constructing {@link PrinterProperty} and {@link FormatProperty} objects from this information and adding them with the methods
* {@link #addProperty(PrinterProperty)} and {@link #addProperty(FormatProperty)}.
* This method is called by ({@link #parseConfigFile(String, boolean)}).
* @param input The input stream to read the configuration from.
* @throws ConfigurationParsingException On any error while accessing the configuration file or syntax.
* @throws ConfigurationValidationException On any error while checking the parsed properties validity.
*/
protected abstract void parse() throws ConfigurationParsingException, ConfigurationValidationException;
protected abstract void parse(FileInputStream input) throws ConfigurationParsingException, ConfigurationValidationException;
/**
......@@ -50,7 +50,7 @@ public abstract class ConfigurationParser {
* @return A {@link File} object representing the configuration file.
*/
public final File getConfigFile() {
return new File(mConfigFilePath);
return mCurrentConfigFile;
}
/**
......@@ -131,14 +131,6 @@ public abstract class ConfigurationParser {
mDefaultFormat = defaultFormat;
}
/**
* Get the input data from the current configuration file.
* @return A {@link FileInputStream} from the current configuration file.
*/
protected FileInputStream getInput() {
return mInput;
}
/**
* Parse the specified configuration file.
* This method should be called inside the concrete parsers constructor after the optional default configurations
......@@ -154,8 +146,10 @@ public abstract class ConfigurationParser {
mPrinterProperties.clear();
mFormatProperties.clear();
// load and parse file
setConfigFile(filePath);
parse();
mCurrentConfigFile = new File(filePath);
FileInputStream input = openInputStream(filePath);
parse(input);
closeInputStream(input);
// build printer object from added properties
mPrinter = new Printer(mPrinterProperties);
if (mDefaultPrinter != null) {
......@@ -177,15 +171,30 @@ public abstract class ConfigurationParser {
}
}
private void setConfigFile(final String filePath) throws ConfigurationParsingException {
mConfigFilePath = filePath;
/**
* Opens the input stream for the given file path.
* @param filePath The file to read from.
* @return A {@link FileInputStream} for the given file path.
* @throws ConfigurationParsingException On any error while opening the stream. (e.g. missing file)
*/
final FileInputStream openInputStream(final String filePath) throws ConfigurationParsingException {
try {
mInput = new FileInputStream(mConfigFilePath);
return new FileInputStream(filePath);
} catch (IOException e) {
throw new ConfigurationParsingException("Unable to read configuration file", e);
}
}
/**
* Closes the given input stream.
* @param input The {@link FileInputStream} to be closed.
* @throws ConfigurationParsingException On any error while closing the stream.
*/
final void closeInputStream(final FileInputStream input) throws ConfigurationParsingException {
try {
input.close();
} catch (IOException e) {
throw new ConfigurationParsingException("Unable to close input stream.", e);
}
}
}
package de.tudresden.inf.mci.brailleplot.configparser;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.Stack;
/**
* Concrete parser for configuration files in Java Property File format.
......@@ -10,7 +13,8 @@ import java.util.Properties;
*/
public final class JavaPropertiesConfigurationParser extends ConfigurationParser {
private Properties mProperties = new Properties();
//ArrayList<String> mInclusionStack;
Stack<File> mInclusionStack = new Stack<>();
/**
* Constructor.
......@@ -33,23 +37,29 @@ public final class JavaPropertiesConfigurationParser extends ConfigurationParser
/**
* Concrete internal algorithm used for parsing the Java Property File.
* This method is called by ({@link #parseConfigFile(String, boolean)}).
* This method is called by ({@link #parseConfigFile(String, boolean)}) and will call itself recursively for every included file.
* @param input The input stream to read the configuration properties from.
* @throws ConfigurationParsingException On any error while accessing the configuration file or syntax.
* @throws ConfigurationValidationException On any error while checking the parsed properties validity.
*/
protected void parse() throws ConfigurationParsingException, ConfigurationValidationException {
// Load properties from the .properties file
protected void parse(final FileInputStream input) throws ConfigurationParsingException, ConfigurationValidationException {
// Create property instance for current recursion level
Properties properties = new Properties();
try {
// Reset java property instance
mProperties.clear();
mProperties.load(getInput());
// Load properties from the .properties file
properties.load(input);
} catch (IOException e) {
throw new ConfigurationParsingException("Unable to load properties from file.", e);
}
// Iterate over all properties as key -> value pairs
for (String key : mProperties.stringPropertyNames()) {
String value = mProperties.getProperty(key);
parseProperty(key, value);
for (String key : properties.stringPropertyNames()) {
String value = properties.getProperty(key);
// check for special property key: 'include'
if (("include").equals(key.toLowerCase())) {
includeFiles(value);
} else {
parseProperty(key, value);
}
}
}
......@@ -62,4 +72,33 @@ public final class JavaPropertiesConfigurationParser extends ConfigurationParser
addProperty((PrinterProperty) property);
}
}
private void includeFiles(final String fileList) throws ConfigurationParsingException, ConfigurationValidationException {
for (String includeName : fileList.split(",")) {
if (mInclusionStack.empty()) {
mInclusionStack.push(getConfigFile());
}
File includeFile, parentFile = mInclusionStack.peek().getParentFile();
try {
String findIncludePath = parentFile.getAbsolutePath() + File.separator + includeName.trim();
File abstractPath = new File(findIncludePath);
if (!abstractPath.exists()) {
abstractPath = new File(findIncludePath + ".properties");
}
includeFile = abstractPath.getCanonicalFile();
} catch (IOException e) {
throw new ConfigurationParsingException("Can not find include file.", e);
}
if (mInclusionStack.contains(includeFile)) {
System.out.println("Skipping " + includeFile);
continue;
}
FileInputStream includeInput = openInputStream(includeFile.getAbsolutePath());
mInclusionStack.push(includeFile);
System.out.println("Including " + mInclusionStack);
parse(includeInput);
mInclusionStack.pop();
closeInputStream(includeInput);
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment