cdc.io.data.util.AbstractResourceLoader Maven / Gradle / Ivy
package cdc.io.data.util;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import cdc.io.compress.Compressor;
import cdc.io.data.Element;
import cdc.io.data.xml.XmlDataReader;
import cdc.util.events.ProgressController;
import cdc.util.events.ProgressSupplier;
import cdc.util.lang.Checks;
import cdc.util.lang.DataException;
import cdc.util.lang.FailureReaction;
/**
* Helper class dedicated to data loading.
*
* @author Damien Carbonne
*
* @param The return type.
*/
public abstract class AbstractResourceLoader {
private final Logger logger;
private final FailureReaction reaction;
private final ProgressSupplier supplier = new ProgressSupplier();
private static final String LOAD_XML = "loadXml({}, {})";
/**
* Creates a Loader with reaction to adopt in case of error.
*
* A logger named from the class is created.
*
* @param reaction The reaction to adopt in case of error.
*/
public AbstractResourceLoader(FailureReaction reaction) {
this.logger = LogManager.getLogger(getClass());
this.reaction = reaction;
}
/**
* @return The logger to use.
*/
public final Logger getLogger() {
return logger;
}
/**
* @return The reaction to adopt in case of error.
*/
public final FailureReaction getReaction() {
return reaction;
}
/**
* Associates a progress controller to this loader.
*
* @param controller The progress controller.
*/
public void setProgressController(ProgressController controller) {
Checks.isNotNull(controller, "controller");
this.supplier.setController(controller);
}
/**
* @return The progress supplier, that can be used to generated progress events.
*/
public ProgressSupplier getProgressSupplier() {
return supplier;
}
/**
* Loads an XML file, possibly compressed.
*
* @param file The file.
* @param compressor The compressor to use (if the file is compressed).
* @param features The enabled XMLDataReader features.
* @return The result.
* @throws IOException When an IO exception occurs.
*/
public final R loadXml(File file,
Compressor compressor,
XmlDataReader.Feature... features) throws IOException {
logger.info(LOAD_XML, file, compressor);
final Element root = XmlDataReader.loadRoot(file, compressor, features);
return loadRoot(root);
}
/**
* Loads an uncompressed XML file.
*
* @param file The file.
* @param features The enabled XMLDataReader features.
* @return The result.
* @throws IOException When an IO exception occurs.
*/
public final R loadXml(File file,
XmlDataReader.Feature... features) throws IOException {
return loadXml(file, Compressor.NONE, features);
}
/**
* Loads an XML file, possibly compressed.
*
* @param filename The file name.
* @param compressor The compressor to use (if the file is compressed).
* @param features The enabled XMLDataReader features.
* @return The result.
* @throws IOException When an IO exception occurs.
*/
public final R loadXml(String filename,
Compressor compressor,
XmlDataReader.Feature... features) throws IOException {
logger.info(LOAD_XML, filename, compressor);
final Element root = XmlDataReader.loadRoot(filename, compressor, features);
return loadRoot(root);
}
/**
* Loads an uncompressed XML file.
*
* @param filename The file name.
* @param features The enabled XMLDataReader features.
* @return The result.
* @throws IOException When an IO exception occurs.
*/
public final R loadXml(String filename,
XmlDataReader.Feature... features) throws IOException {
return loadXml(filename, Compressor.NONE, features);
}
/**
* Loads an XML URL, possibly compressed.
*
* @param url The URL.
* @param compressor The compressor to use (if the file is compressed).
* @param features The enabled XMLDataReader features.
* @return The result.
* @throws IOException When an IO exception occurs.
*/
public final R loadXml(URL url,
Compressor compressor,
XmlDataReader.Feature... features) throws IOException {
logger.info(LOAD_XML, url, compressor);
final Element root = XmlDataReader.loadRoot(url, compressor, features);
return loadRoot(root);
}
/**
* Loads an uncompressed XML URL.
*
* @param url The URL.
* @param features The enabled XMLDataReader features.
* @return The result.
* @throws IOException When an IO exception occurs.
*/
public final R loadXml(URL url,
XmlDataReader.Feature... features) throws IOException {
return loadXml(url, Compressor.NONE, features);
}
/**
* Loads a list of XML URLs, possibly compressed.
*
* @param urls The list of URLs.
* @param compressor The compressor to use (if the URLs are compressed).
* @param features The enabled XMLDataReader features.
* @throws IOException When an IO exception occurs.
*/
public final void loadXml(List urls,
Compressor compressor,
XmlDataReader.Feature... features) throws IOException {
for (final URL url : urls) {
loadXml(url, compressor, features);
}
}
/**
* Loads a list of uncompressed XML URLs.
*
* @param urls The list of URLs.
* @param features The enabled XMLDataReader features.
* @throws IOException When an IO exception occurs.
*/
public final void loadXml(List urls,
XmlDataReader.Feature... features) throws IOException {
loadXml(urls, Compressor.NONE, features);
}
/**
* Loads an XML input stream, possibly compressed.
*
* @param is The input stream.
* @param systemId The system id.
* @param compressor The compressor to use (if the input stream is compressed).
* @param features The enabled XMLDataReader features.
* @return The result.
* @throws IOException When an IO exception occurs.
*/
public final R loadXml(InputStream is,
String systemId,
Compressor compressor,
XmlDataReader.Feature... features) throws IOException {
logger.info(LOAD_XML, systemId, compressor);
final Element root = XmlDataReader.loadRoot(is, systemId, compressor, features);
return loadRoot(root);
}
/**
* Loads an uncompressed XML input stream.
*
* @param is The input stream.
* @param systemId The system id.
* @param features The enabled XMLDataReader features.
* @return The result.
* @throws IOException When an IO exception occurs.
*/
public final R loadXml(InputStream is,
String systemId,
XmlDataReader.Feature... features) throws IOException {
return loadXml(is, systemId, Compressor.NONE, features);
}
/**
* Method that must be implemented by concrete classes to load the file.
*
* @param root The root element.
* @return The result.
* @throws IOException When an IO exception occurs.
*/
protected abstract R loadRoot(Element root) throws IOException;
/**
* Function that either keeps silent, warns or raises an exception,
* depending on error reaction.
*
* @param message The error message.
* @throws DataException When error reaction is {@link FailureReaction#FAIL}.
*/
protected final void onError(String message) {
FailureReaction.onError(message, logger, reaction, DataException::new);
}
/**
* Function that either silently returns a value, warns and returns a value
* or raises an exception, depending on error reaction.
*
* @param The return type.
* @param message The error message.
* @param def The default return value.
* @return {@code def} if error reaction is {@link FailureReaction#DEFAULT}
* or {@link FailureReaction#WARN}.
* @throws DataException When error reaction is {@link FailureReaction#FAIL}.
*/
protected final T onError(String message,
T def) {
return FailureReaction.onError(message, logger, reaction, def, DataException::new);
}
/**
* Function that returns a computed value if it is not {@code null},
* or silently returns a default value, warns and returns a default value
* or throws an exception.
*
* @param The return type.
* @param result The computed result.
* @param message The error message.
* @param def The default return value.
* @return {@code result} if it is not {@code null}, or {@code def} if
* error reaction is {@link FailureReaction#DEFAULT}
* or {@link FailureReaction#WARN}.
* @throws DataException When {@code result} is {@code null}
* and error reaction is {@link FailureReaction#FAIL}.
*/
protected final T onResult(T result,
String message,
T def) {
return FailureReaction.onResult(result, message, logger, reaction, def, DataException::new);
}
protected final void unexpectedElement(Element element,
String... expected) {
unexpectedElement(element, null, expected);
}
protected final V unexpectedElement(Element element,
V def,
String... expected) {
if (expected == null || expected.length == 0) {
return onError("Unexpected child " + element + " under " + element.getParent(), def);
} else {
return onError("Unexpected child " + element + " under " + element.getParent()
+ " expected one of " + Arrays.toString(expected), def);
}
}
}