
com.github.nicosensei.textbatch.BatchExecutor Maven / Gradle / Ivy
/**
*
*/
package com.github.nicosensei.textbatch;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.InvalidPropertiesFormatException;
import java.util.List;
import java.util.Properties;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import com.github.nicosensei.commons.utils.FileUtils;
import com.github.nicosensei.commons.utils.datatype.TimeFormatter;
/**
*
* Generic batch executors that wraps basic services such as property injection and logging.
* @author ngiraud
*
*/
public final class BatchExecutor {
private class BatchSettings extends Properties {
private static final long serialVersionUID = 4321353542724244541L;
public static final String BASE_PACKAGE_PROP_KEY = "basePackage";
private final String basePackage;
private BatchSettings(String filePath)
throws InvalidPropertiesFormatException, IOException {
FileInputStream fis = new FileInputStream(filePath);
loadFromXML(fis);
basePackage = getProperty(BASE_PACKAGE_PROP_KEY);
if (basePackage == null) {
throw new InvalidPropertiesFormatException(
"Must define a " + BASE_PACKAGE_PROP_KEY + " property!");
}
}
public String getPropertyKey(Class> owner, String name) {
String prefix = owner.getName();
if (!basePackage.isEmpty()) {
prefix = prefix.replaceFirst(basePackage + "\\.", "");
}
return prefix + "." + name;
}
}
private class BatchLogger {
private static final String DFT_LOG_PATTERN = "%m%n";
public final String logPattern;
private String errorFile;
private Logger errorLogger;
private String logFile;
private Logger logger;
private final File logFolder;
private BatchLogger(
BatchSettings settings,
String name,
String dateLayout,
String logPattern) throws IOException {
if (logPattern == null || logPattern.isEmpty()) {
this.logPattern = DFT_LOG_PATTERN;
} else {
this.logPattern = logPattern;
}
this.logFolder = new File(getProperty(BatchExecutor.class, "log.folder"));
if (! this.logFolder.exists()) {
this.logFolder.mkdir();
} else if (! this.logFolder.isDirectory()
|| ! this.logFolder.canWrite()) {
System.err.println("Can't initialize log folder!");
System.exit(-1);
}
Logger rootLogger = Logger.getRootLogger();
if (! rootLogger.getAllAppenders().hasMoreElements()) {
rootLogger.addAppender(new ConsoleAppender(
new PatternLayout(this.logPattern)));
}
rootLogger.setLevel(Level.ERROR);
rootLogger.setAdditivity(false);
logger = Logger.getLogger(name);
logger.addAppender(
new ConsoleAppender(new PatternLayout(this.logPattern)));
logFile = logFolder.getAbsolutePath()
+ File.separator + name
+ "_" + new SimpleDateFormat(dateLayout).format(new Date())
+ ".out";
logger.addAppender(
new FileAppender(new PatternLayout(this.logPattern), logFile));
logger.setLevel(Level.DEBUG);
logger.setAdditivity(false);
logger.info("Log folder is: " + logFolder.getAbsolutePath());
logger.info("Console output logged to: " + logFile);
errorLogger = Logger.getLogger(name + ".err");
errorFile = logFolder.getAbsolutePath() + File.separator
+ name + ".err.log";
errorLogger.addAppender(
new FileAppender(new PatternLayout(this.logPattern), errorFile));
errorLogger.setLevel(Level.ERROR);
errorLogger.setAdditivity(false);
}
}
private static BatchExecutor instance;
private BatchSettings settings;
private BatchLogger logger;
private List filesToClean = new ArrayList();
private BatchExecutor(String settingsFilePath, String name)
throws InvalidPropertiesFormatException, IOException {
settings = new BatchSettings(settingsFilePath);
logger = new BatchLogger(
settings,
name,
getProperty(BatchExecutor.class, "log.dateLayout"),
getProperty(BatchExecutor.class, "log.pattern"));
}
public static void launch(
final String settingsXmlPath,
final Class> batchClass,
final String... args) {
long initTime = System.currentTimeMillis();
try {
BatchExecutor.init(settingsXmlPath, batchClass.getSimpleName());
} catch (Exception e) {
e.printStackTrace(System.err);
System.err.println("Failed to initialize batch!");
System.exit(-1);
}
BatchState state = null;
try {
Batch, ?> batch = (Batch, ?>) batchClass.newInstance();
batch.initialize(args);
batch.launch();
state = batch.getBatchState();
} catch (BatchException e) {
if (Level.FATAL.equals(e.getCriticity())) {
BatchExecutor.getInstance().logInfo("Fatal error encountered!");
System.exit(-1);
}
} catch (Throwable t) {
instance.logInfo("Caught "+ t.getLocalizedMessage());
instance.logError(t);
System.exit(-1);
} finally {
cleanup(state, initTime);
}
}
public static void init(String settingsFilePath, String name)
throws InvalidPropertiesFormatException, IOException {
if (instance == null) {
instance = new BatchExecutor(settingsFilePath, name);
}
}
public static BatchExecutor getInstance() {
return instance;
}
public void registerFileForCleanup(File f) {
filesToClean.add(f);
}
public void registerFileForCleanup(String f) {
filesToClean.add(new File(f));
}
public synchronized void logDebug(String msg) {
logger.logger.debug(msg);
}
public synchronized void logInfo(String msg) {
logger.logger.info(msg);
}
public synchronized void logWarning(String msg) {
logger.logger.warn(msg);
}
public synchronized void logError(Throwable t) {
String msg = t.getLocalizedMessage();
logger.logger.warn(msg);
logger.errorLogger.error(msg, t);
}
public File getLogFolder() {
return logger.logFolder;
}
public String getProperty(Class> owner, String key) {
return settings.getProperty(settings.getPropertyKey(owner, key));
}
public int getIntProperty(Class> owner, String key) {
return Integer.parseInt(settings.getProperty(settings.getPropertyKey(owner, key)));
}
public int getIntProperty(Class> owner, String key, int defaultValue) {
String value = settings.getProperty(settings.getPropertyKey(owner, key));
return (value == null ? defaultValue : Integer.parseInt(value));
}
public long getLongProperty(Class> owner, String key) {
return Long.parseLong(settings.getProperty(settings.getPropertyKey(owner, key)));
}
public long getLongProperty(Class> owner, String key, long defaultValue) {
String value = settings.getProperty(settings.getPropertyKey(owner, key));
return (value == null ? defaultValue : Long.parseLong(value));
}
public boolean getBoolProperty(Class> owner, String key) {
return Boolean.parseBoolean(
settings.getProperty(settings.getPropertyKey(owner, key)));
}
public boolean getBoolProperty(
Class> owner, String key, boolean defaultValue) {
String value = settings.getProperty(settings.getPropertyKey(owner, key));
return (value == null ? defaultValue : Boolean.parseBoolean(value));
}
public static void cleanup(BatchState state, long initTime) {
// Register error log for cleanup if it's empty
File errorLog = new File(instance.logger.errorFile);
if (errorLog.exists() && (errorLog.length() == 0)) {
instance.registerFileForCleanup(errorLog);
}
// Clean registered files
for (File f : instance.filesToClean) {
try {
FileUtils.recursiveDelete(f);
} catch (final IOException e) {
instance.logError(e);
}
}
if (state != null) {
state.logStatus();
}
long timeElapsed = System.currentTimeMillis() - initTime;
instance.logInfo("Time elapsed: " + TimeFormatter.formatDuration(timeElapsed));
LogManager.shutdown();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy