/**
*
*/
package cz.cuni.mff.peckam.java.origamist.logging;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.ResourceBundle;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Layout;
import org.apache.log4j.Level;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.spi.LoggingEvent;
import cz.cuni.mff.peckam.java.origamist.configuration.Configuration;
import cz.cuni.mff.peckam.java.origamist.gui.common.CommonGui;
import cz.cuni.mff.peckam.java.origamist.services.ServiceLocator;
import cz.cuni.mff.peckam.java.origamist.services.interfaces.ConfigurationManager;
/**
* This appender writes the appMessages to the console. FATAL appMessages are also shown as error popups to the user.
*
* By default, it uses System.err and a PatternLayout.
*
* @author Martin Pecka
*/
public class GUIAppender extends ConsoleAppender
{
/** The localized appMessages for the "application" bundle. */
protected ResourceBundle messages = null;
/** The message formater that can be used. It has its locale set to the configured one. */
protected MessageFormat format = null;
/** The GUI we can use to show error popups. */
protected CommonGui gui = null;
/**
* Use PatternLayout and System.err.
*
* @param gui The GUI we can use to show error popups.
*/
public GUIAppender(CommonGui gui)
{
this(gui, new PatternLayout(), ConsoleAppender.SYSTEM_ERR);
}
/**
* @param gui The GUI we can use to show error popups.
* @param layout The layout to use.
* @param target Either SYSTEM_OUT or SYSTEM_ERR.
*/
public GUIAppender(CommonGui gui, Layout layout, String target)
{
super(layout, target);
this.gui = gui;
final Configuration config = ServiceLocator.get(ConfigurationManager.class).get();
messages = ResourceBundle.getBundle("application", config.getLocale());
format = new MessageFormat("", config.getLocale());
config.addPropertyChangeListener("locale", new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt)
{
if (!messages.getLocale().equals(evt.getNewValue())) {
messages = ResourceBundle.getBundle("application", (Locale) evt.getNewValue());
format = new MessageFormat("", (Locale) evt.getNewValue());
}
}
});
}
/**
* Use SYSTEM_ERR as the default target.
*
* @param gui The GUI we can use to show error popups.
* @param layout The layout to use.
*/
public GUIAppender(CommonGui gui, Layout layout)
{
this(gui, layout, ConsoleAppender.SYSTEM_ERR);
}
@Override
public synchronized void doAppend(LoggingEvent event)
{
super.doAppend(event);
if (event.getLevel().isGreaterOrEqual(Level.FATAL)) {
final Throwable t = event.getThrowableInformation() == null ? null : event.getThrowableInformation()
.getThrowable();
String desc = this.layout.format(event);
final String desc2 = desc != null ? desc : messages.getString("unknownError");
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run()
{
format.applyPattern(messages.getString("dieWithException"));
JOptionPane.showMessageDialog(gui.getRootPane(),
format.format(new String[] { desc2, t == null ? "" : t.toString() }),
messages.getString("dieWithExceptionTitle"), JOptionPane.ERROR_MESSAGE);
gui.stop();
}
});
}
}
}