/*******************************************************************************
* Copyright (c) MOBAC developers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package mobac.program;
import java.awt.Desktop;
import java.awt.Desktop.Action;
import java.io.File;
import java.io.StringWriter;
import java.util.Enumeration;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.TreeMap;
import java.util.logging.Handler;
import mobac.StartMOBAC;
import mobac.utilities.GUIExceptionHandler;
import mobac.utilities.Juli2Log4jHandler;
import mobac.utilities.OSUtilities;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Layout;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.SimpleLayout;
import org.apache.log4j.xml.DOMConfigurator;
public class Logging {
protected static final String CONFIG_FILENAME = "log4j.xml";
protected static final String LOG_FILENAME = "Mobile Atlas Creator.log";
protected static File CONFIG_FILE = null;
public static final Logger LOG = Logger.getLogger("MAC");
public static final Layout ADVANCED_LAYOUT = new PatternLayout("%d{ISO8601} %-5p [%t] %c{1}: %m%n");
protected static boolean CONFIGURED = false;
public static void configureLogging() {
// We test for the configuration file, if it exists we use it, otherwise
// we perform simple logging to the console
if (!loadLog4JConfigXml()) {
configureDefaultErrorLogging();
Logger logger = Logger.getRootLogger();
logger.info("log4.xml not found - enabling default error log to console");
}
}
public static boolean loadLog4JConfigXml() {
if (loadLog4JConfigXml(DirectoryManager.userAppDataDir))
return true;
if (loadLog4JConfigXml(DirectoryManager.userSettingsDir))
return true;
if (loadLog4JConfigXml(DirectoryManager.currentDir))
return true;
if (loadLog4JConfigXml(DirectoryManager.programDir))
return true;
return false;
}
public static boolean loadLog4JConfigXml(File directory) {
File f = new File(directory, CONFIG_FILENAME);
if (!f.isFile())
return false;
try {
DOMConfigurator.configure(f.getAbsolutePath());
} catch (Exception e) {
System.err.println("Error loading log4j config file \"" + f.getAbsolutePath() + "\"");
return false;
}
Logger logger = Logger.getLogger("LogSystem");
logger.setLevel(Level.INFO);
logger.info("Logging configured by \"" + f.getAbsolutePath() + "\"");
CONFIGURED = true;
return true;
}
public static void configureDefaultErrorLogging() {
Logger.getRootLogger().setLevel(Level.INFO);
configureConsoleLogging(Level.TRACE, new SimpleLayout());
configureLogFileLogging(Level.TRACE);
}
public static void configureConsoleLogging() {
configureConsoleLogging(Level.ERROR, new SimpleLayout());
}
public static void configureConsoleLogging(Level level) {
configureConsoleLogging(level, new SimpleLayout());
}
public static void configureConsoleLogging(Level level, Layout layout) {
Logger logger = Logger.getRootLogger();
ConsoleAppender consoleAppender = new ConsoleAppender(layout);
if (level != null)
consoleAppender.setThreshold(level);
logger.addAppender(consoleAppender);
CONFIGURED = true;
}
public static void configureLogFileLogging(Level level) {
Logger logger = Logger.getRootLogger();
File logFileDir = DirectoryManager.userAppDataDir;
String logFilename = new File(logFileDir, LOG_FILENAME).getAbsolutePath();
Layout layout = new PatternLayout("%d{ISO8601} %-5p [%t] %c{1}: %m%n");
FileAppender fileAppender;
try {
fileAppender = new FileAppender(layout, logFilename, false);
if (level != null)
fileAppender.setThreshold(level);
logger.addAppender(fileAppender);
} catch (Exception e) {
Logger log = Logger.getLogger("LogSystem");
log.error("", e);
}
}
public static void disableLogging() {
Logger logger = Logger.getRootLogger();
logger.setLevel(Level.OFF);
}
public static void enableJAXBLogging() {
java.util.logging.Logger logger;
Handler h = new Juli2Log4jHandler();
logger = java.util.logging.Logger.getLogger("javax.xml.bind");
logger.setLevel(java.util.logging.Level.ALL);
logger.addHandler(h);
logger = java.util.logging.Logger.getLogger("com.sun.xml.internal.bind");
logger.setLevel(java.util.logging.Level.ALL);
logger.addHandler(h);
}
public static void logSystemInfo() {
Logger log = Logger.getLogger("SysInfo");
if (log.isInfoEnabled()) {
String n = System.getProperty("line.separator");
log.info("Version: " + ProgramInfo.getCompleteTitle());
log.info("Platform: " + GUIExceptionHandler.prop("os.name") + " (" + GUIExceptionHandler.prop("os.version")
+ ")");
log.info("Java VM: " + GUIExceptionHandler.prop("java.vm.name") + " ("
+ GUIExceptionHandler.prop("java.runtime.version") + ")");
log.info("Directories:" /**/
+ n + "currentDir: \t\t" + DirectoryManager.currentDir /**/
+ n + "programDir: \t\t" + DirectoryManager.programDir /**/
+ n + "tempDir: \t\t" + DirectoryManager.tempDir /**/
+ n + "userHomeDir: \t\t" + DirectoryManager.userHomeDir /**/
+ n + "userSettingsDir: \t" + DirectoryManager.userSettingsDir /**/
+ n + "atlasProfilesDir: \t" + DirectoryManager.atlasProfilesDir /**/
+ n + "userAppDataDir: \t" + DirectoryManager.userAppDataDir /**/
);
log.info("System console available: " + (System.console() != null));
log.info("Startup arguments (count=" + StartMOBAC.ARGS.length + "):");
for (int i = 0; i < StartMOBAC.ARGS.length; i++)
log.info("\t" + i + ": " + StartMOBAC.ARGS[i]);
}
if (log.isDebugEnabled()) {
log.debug("Detected operating system: " + OSUtilities.detectOs() + " (" + System.getProperty("os.name")
+ ")");
boolean desktopSupport = Desktop.isDesktopSupported();
log.debug("Desktop support: " + desktopSupport);
if (desktopSupport) {
Desktop d = Desktop.getDesktop();
for (Action a : Action.values()) {
log.debug("Desktop action " + a + " supported: " + d.isSupported(a));
}
}
}
if (log.isTraceEnabled()) {
Properties props = System.getProperties();
StringWriter sw = new StringWriter(2 << 13);
sw.write("System properties:\n");
TreeMap<Object, Object> sortedProps = new TreeMap<Object, Object>(props);
for (Entry<Object, Object> entry : sortedProps.entrySet()) {
sw.write(entry.getKey() + " = " + entry.getValue() + "\n");
}
log.trace(sw.toString());
}
}
/**
* returns the first configured {@link FileAppender} or <code>null</code>.
*
* @return
*/
public static String getLogFile() {
Enumeration<?> enu = Logger.getRootLogger().getAllAppenders();
while (enu.hasMoreElements()) {
Object o = enu.nextElement();
if (o instanceof FileAppender) {
FileAppender fa = (FileAppender) o;
return fa.getFile();
}
}
return null;
}
public static boolean isCONFIGURED() {
return CONFIGURED;
}
}