package com.cedarsoft.spring.rcp.dialog;
import org.jdesktop.swingx.JXErrorPane;
import org.jdesktop.swingx.error.ErrorInfo;
import org.jdesktop.swingx.error.ErrorReporter;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.richclient.exceptionhandling.MessagesDialogExceptionHandler;
import org.springframework.richclient.exceptionhandling.ShutdownPolicy;
import java.util.logging.Level;
/**
* Dialog based exception handler
*/
public class DialogExceptionHandler extends MessagesDialogExceptionHandler {
private ErrorReporter errorReporter;
/**
* No shutDownPolicy can be used in conjunction with the {@link org.jdesktop.swingx.JXErrorPane}.
*/
@Override
public void setShutdownPolicy( @NotNull ShutdownPolicy shutdownPolicy ) {
throw new UnsupportedOperationException( "JXErrorDialogExceptionHandler does not support setting of ShutdownPolicy" );
}
/**
* Add an {@link ErrorReporter} to the {@link org.jdesktop.swingx.JXErrorPane}.
*
* @param errorReporter error reporter to add.
*/
public void setErrorReporter( ErrorReporter errorReporter ) {
this.errorReporter = errorReporter;
}
/**
* Shows the {@link org.jdesktop.swingx.JXErrorPane} to the user.
*/
@Override
public void notifyUserAboutException( Thread thread, Throwable throwable ) {
ErrorInfo errorInfo = new ErrorInfo( resolveExceptionCaption( throwable ), ( String ) createExceptionContent( throwable ), getDetailsAsHTML( throwable.getMessage(), resolveMessageType(), throwable ), null, throwable, resolveMessageType(), null );
JXErrorPane pane = new JXErrorPane();
pane.setErrorInfo( errorInfo );
if ( errorReporter != null ) {
pane.setErrorReporter( errorReporter );
}
JXErrorPane.showDialog( resolveParentFrame(), pane );
}
/**
* Resolve the Spring logLevel to java Level.
*
* @return the level
*/
@NotNull
private Level resolveMessageType() {
switch ( logLevel ) {
case TRACE:
return Level.FINEST;
case DEBUG:
return Level.FINER;
case INFO:
return Level.INFO;
case WARN:
return Level.WARNING;
case ERROR:
case FATAL:
default:
return Level.SEVERE;
}
}
/**
* Converts the incoming string to an escaped output string. This method is
* far from perfect, only escaping <, > and & characters
*
* @param input the input
* @return the escaped xml
*/
@NotNull
@NonNls
private static String escapeXml( @NotNull @NonNls String input ) {
return input == null ? "" : input.replace( "&", "&" ).replace( "<", "<" ).replace( ">", ">" );
}
/**
* Creates and returns HTML representing the details of this incident info.
* This method is only called if the details needs to be generated: ie: the
* detailed error message property of the incident info is null.
*
* @param title the title
* @param level the level
* @param e the exception
* @return the string
*/
@Nullable
private static String getDetailsAsHTML( @NotNull String title, @NotNull Level level, @Nullable Throwable e ) {
if ( e == null ) {
return null;
}
StringBuffer html = new StringBuffer( "<html>" );
html.append( "<h2>" + escapeXml( title ) + "</h2>" );
html.append( "<HR size='1' noshade>" );
html.append( "<div></div>" );
html.append( "<b>Message:</b>" );
html.append( "<pre>" );
html.append( " " + escapeXml( e.toString() ) );
html.append( "</pre>" );
html.append( "<b>Level:</b>" );
html.append( "<pre>" );
html.append( " " + level );
html.append( "</pre>" );
html.append( "<b>Stack Trace:</b>" );
html.append( "<pre>" );
for ( StackTraceElement el : e.getStackTrace() ) {
html.append( " " + el.toString().replace( "<init>", "<init>" ) + "\n" );
}
Throwable cause = e.getCause();
while ( cause != null ) {
appendCause( cause, html );
cause = cause.getCause();
}
html.append( "</pre></html>" );
return html.toString();
}
private static void appendCause( @NotNull Throwable e, @NotNull @NonNls StringBuffer html ) {
html.append( "</pre>" );
html.append( "<b>Cause:</b>" );
html.append( "<pre>" );
html.append( e.getCause().getMessage() );
html.append( "</pre><pre>" );
for ( StackTraceElement el : e.getCause().getStackTrace() ) {
html.append( " " + el.toString().replace( "<init>", "<init>" ) + "\n" );
}
}
}