
com.github.nicosensei.textbatch.Tool 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.Arrays;
import java.util.Date;
import java.util.InvalidPropertiesFormatException;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.DailyRollingFileAppender;
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.textbatch.job.JobController;
import com.github.nicosensei.textbatch.job.JobProgress;
import com.github.nicosensei.textbatch.job.ResultLogger;
/**
*
* Allows access to a tool basic functions.
* @author ngiraud
*
*/
public class Tool {
private class ToolSettings extends Properties {
private static final long serialVersionUID = 4321353542724244541L;
public static final String BASE_PACKAGE_PROP_KEY = "basePackage";
private final String basePackage;
private ToolSettings(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 ToolLogger {
private static final String DFT_DATE_LAYOUT = "yyyy-MM-dd_HH:mm";
private static final String DFT_LOG_PATTERN = "%m%n";
public final String dateLayout;
// public static final String TIME_LAYOUT = "HH:mm:ss:SSS";
// public static final String LOG_PATTERN = "%d{" + TIME_LAYOUT
// + "} %-5p [%t]: %m%n";
public final String logPattern;
private String errorFile;
private Logger errorLogger;
private ResultLogger errorSummaryLogger;
private String logFile;
private Logger logger;
private final File logFolder;
private ToolLogger(
ToolSettings settings,
String name,
String dateLayout,
String logPattern) throws IOException {
boolean defaultedDateLayout = false;
if (dateLayout == null || dateLayout.isEmpty()) {
this.dateLayout = DFT_DATE_LAYOUT;
defaultedDateLayout = true;
} else {
this.dateLayout = dateLayout;
}
boolean defaultedLogPattern = false;
if (logPattern == null || logPattern.isEmpty()) {
this.logPattern = DFT_LOG_PATTERN;
defaultedLogPattern = true;
} else {
this.logPattern = logPattern;
}
this.logFolder = new File(getProperty(Tool.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 DailyRollingFileAppender(new PatternLayout(
this.logPattern), errorFile, "."
+ this.dateLayout));
errorLogger.setLevel(Level.ERROR);
errorLogger.setAdditivity(false);
if (defaultedDateLayout) {
logger.warn("Rolling log date pattern set to default.");
}
if (defaultedLogPattern) {
logger.warn("Log entry pattern set to default.");
}
}
public void setErrorSummaryLogger(ResultLogger logger) {
this.errorSummaryLogger = logger;
}
}
private static Tool instance;
private ToolSettings settings;
private ToolLogger logger;
private List filesToClean = new ArrayList();
private Tool(String settingsFilePath, String name)
throws InvalidPropertiesFormatException, IOException {
settings = new ToolSettings(settingsFilePath);
logger = new ToolLogger(
settings,
name,
getProperty(Tool.class, "log.dateLayout"),
getProperty(Tool.class, "log.pattern"));
}
public static void main(String[] args) {
if (args.length < 2) {
System.out.println("Missing mandatory arguments:");
System.out.println("\t0: ");
System.out.println("\t1: ");
System.exit(0);
}
String settingsFile = args[0];
String jobCtrlClass = args[1];
long initTime = System.currentTimeMillis();
try {
Tool.init(settingsFile, jobCtrlClass);
} catch (Exception e) {
e.printStackTrace(System.err);
System.err.println("Failed to initialize tool!");
System.exit(-1);
}
JobProgress progress = null;
try {
Class> jcClass = Class.forName(jobCtrlClass);
JobController, ?> jc =
(JobController, ?>) jcClass.newInstance();
jc.initialize(subArgs(args, 2));
jc.launch();
progress = jc.getProgress();
} catch (ToolException e) {
if (Level.FATAL.equals(e.getCriticity())) {
Tool.getInstance().logInfo("Fatal error encountered!");
System.exit(-1);
}
} catch (Throwable t) {
instance.logInfo("Caught "+ t.getLocalizedMessage());
instance.logError(t);
System.exit(-1);
} finally {
cleanup(progress, initTime);
}
}
public static void init(String settingsFilePath, String name)
throws InvalidPropertiesFormatException, IOException {
if (instance == null) {
instance = new Tool(settingsFilePath, name);
}
}
public static Tool 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.error(msg, t);
logger.errorLogger.error(msg, t);
if (logger.errorSummaryLogger != null) {
if (t instanceof ToolException) {
logger.errorSummaryLogger.logResult(
((ToolException) t).getRootCause()
.getLocalizedMessage());
}
}
}
public synchronized void logError(ToolException e) {
String msg = e.getLocalizedMessage();
if (e.isVerbose()) {
logger.logger.error(msg, e);
}
logger.errorLogger.error(msg, e);
if (logger.errorSummaryLogger != null) {
if (e instanceof ToolException) {
logger.errorSummaryLogger.logResult(
((ToolException) e).getRootCause()
.getLocalizedMessage());
}
}
}
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 String formatDuration(long lMs) {
// Validate
if (lMs > 0L) {
// -- Declare variables
String strDays = "";
String strHours = "";
String strMinutes = "";
String strSeconds = "";
String strMillisecs = "";
String strReturn = "";
long lRest;
// -- Find values
// -- -- Days
strDays = String.valueOf(lMs / 86400000L);
lRest = lMs % 86400000L;
// -- -- Hours
strHours = String.valueOf(lRest / 3600000L);
lRest %= 3600000L;
// -- -- Minutes
strMinutes = String.valueOf(lRest / 60000L);
lRest %= 60000L;
// -- -- Seconds
strSeconds = String.valueOf(lRest / 1000L);
lRest %= 1000L;
// -- -- Milliseconds
strMillisecs = String.valueOf(lRest);
// -- Format return
// -- -- Days
if (new Integer(strDays).intValue() != 0) {
strReturn += strDays + "day ";
}
// -- -- Hours
if (new Integer(strHours).intValue() != 0) {
strReturn += strHours + "hr ";
}
// -- -- Minutes
if (new Integer(strMinutes).intValue() != 0) {
strReturn += strMinutes + "min ";
}
// -- -- Seconds
if (new Integer(strSeconds).intValue() != 0) {
strReturn += strSeconds + "sec ";
}
// -- -- Milliseconds
if (new Integer(strMillisecs).intValue() != 0) {
strReturn += strMillisecs + "ms";
}
return strReturn;
} else if (lMs == 0L) {
return "0ms";
} else {
return "-1";
}
}
public static void cleanup(JobProgress progress, 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) {
deleteFileRec(f);
}
if (progress != null) {
progress.logStatus();
}
long timeElapsed = System.currentTimeMillis() - initTime;
instance.logInfo("Time elapsed: " + formatDuration(timeElapsed));
LogManager.shutdown();
}
public void setErrorSummaryLogger(ResultLogger logger) {
this.logger.setErrorSummaryLogger(logger);
}
private static String[] subArgs(String[] args, int beginIndex) {
LinkedList subArgs =
new LinkedList(Arrays.asList(args));
for (int i = 0; i < beginIndex; i++) {
subArgs.removeFirst();
}
return (String[]) subArgs.toArray(new String[subArgs.size()]);
}
private static void deleteFileRec(File f) {
if (f.isDirectory()) {
for (File child : f.listFiles()) {
deleteFileRec(child);
}
}
if (!f.delete()) {
f.deleteOnExit();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy