/*****************************************************************************
* Copyright (c) 2008 g-Eclipse Consortium
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Initial development of the original code was made for the
* g-Eclipse project founded by European Union
* project number: FP6-IST-034327 http://www.geclipse.eu/
*
* Contributors:
* Mathias Stuempert - initial API and implementation
* Ariel Garcia - modified to work for any Throwable
*****************************************************************************/
package eu.geclipse.ui.internal.dialogs;
import java.io.PrintWriter;
import java.io.StringWriter;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import eu.geclipse.core.reporting.IProblem;
import eu.geclipse.core.reporting.ISolution;
import eu.geclipse.core.reporting.ProblemException;
/**
* This class creates a problem report for a given {@link Throwable}.
*/
public class ProblemReport {
private static final String PLUG_IN_HEADER = "Plug-In"; //$NON-NLS-1$
private static final String CONTACT_ADDRESS_HEADER = "Contact Address"; //$NON-NLS-1$
private static final String DESCRIPTION_HEADER = "Description"; //$NON-NLS-1$
private static final String REASONS_HEADER = "Reasons"; //$NON-NLS-1$
private static final String SOLUTIONS_HEADER = "Proposed Solutions"; //$NON-NLS-1$
private static final String STACKTRACE_HEADER = "Stacktrace"; //$NON-NLS-1$
private static final String SEVERITY_HEADER = "Severity"; //$NON-NLS-1$
private static final String THROWABLE_DESCRIPTION_TEXT = "Caught an exception: "; //$NON-NLS-1$
private static final String HEADER_PREFIX = ":"; //$NON-NLS-1$
private static final String FIELD_PREFIX = "\t"; //$NON-NLS-1$
private static final String SOLUTION_FORMAT = "%s (ID=%s)"; //$NON-NLS-1$
private static final String NA_STRING = "N/A"; //$NON-NLS-1$
/**
* The throwable for which to create a report.
*/
private Throwable exc;
/**
* Create a new problem report for the given {@link Throwable}.
*
* @param throwable The throwable for which to create the report.
*/
public ProblemReport( final Throwable throwable ) {
this.exc = throwable;
}
/**
* Create and return the report.
*
* @return The created report as {@link String}.
*/
public String createReport() {
IProblem problem = null;
IStatus status = null;
if ( this.exc instanceof ProblemException ) {
problem = ( ( ProblemException ) this.exc ).getProblem();
} else if ( this.exc instanceof CoreException ) {
status = ( ( CoreException ) this.exc ).getStatus();
}
StringWriter sWriter = new StringWriter();
PrintWriter pWriter = new PrintWriter( sWriter );
if ( problem != null ) {
// A ProblemException
writeField( pWriter, PLUG_IN_HEADER, problem.getPluginID() );
writeField( pWriter, CONTACT_ADDRESS_HEADER, problem.getMailTo() );
writeField( pWriter, DESCRIPTION_HEADER, problem.getDescription() );
writeField( pWriter, REASONS_HEADER, problem.getReasons() );
writeField( pWriter, SOLUTIONS_HEADER, problem.getSolutions() );
} else if ( status != null ) {
// A CoreException
writeField( pWriter, PLUG_IN_HEADER, status.getPlugin() );
writeField( pWriter, DESCRIPTION_HEADER, status.getMessage() );
writeField( pWriter, SEVERITY_HEADER, severity( status.getSeverity() ) );
} else {
// Any other Throwable
writeField( pWriter,
DESCRIPTION_HEADER,
THROWABLE_DESCRIPTION_TEXT + this.exc.getClass().getName() );
}
writeField( pWriter, STACKTRACE_HEADER, this.exc );
pWriter.close();
return sWriter.toString();
}
/**
* Converts the integer severity value carried by a CoreException to a string.
*
* @param severity one of {@link IStatus.OK}, {@link IStatus.INFO},
* {@link IStatus.WARNING}, {@link IStatus.ERROR}, {@link IStatus.CANCEL}.
* @return a string describing the severity.
*/
private String severity( final int severity ) {
String sSeverity = NA_STRING;
switch ( severity ) {
case IStatus.OK :
sSeverity = "OK"; //$NON-NLS-1$
break;
case IStatus.INFO :
sSeverity = "INFO"; //$NON-NLS-1$
break;
case IStatus.WARNING :
sSeverity = "WARNING"; //$NON-NLS-1$
break;
case IStatus.ERROR :
sSeverity = "ERROR"; //$NON-NLS-1$
break;
case IStatus.CANCEL :
sSeverity = "CANCEL"; //$NON-NLS-1$
break;
default:
sSeverity = NA_STRING;
}
return sSeverity;
}
/**
* Write the specified {@link Throwable} to the specified {@link PrintWriter}.
*
* @param writer The {@link PrintWriter} where the field should be written to.
* @param header The header used to specify the field.
* @param t The {@link Throwable} to be written.
*/
private void writeField( final PrintWriter writer,
final String header,
final Throwable t ) {
if ( t == null ) {
writeField( writer, header, NA_STRING );
} else {
StringWriter sWriter = new StringWriter();
PrintWriter pWriter = new PrintWriter( sWriter );
t.printStackTrace( pWriter );
pWriter.close();
writeField( writer, header, sWriter.toString() );
}
}
/**
* Write the specified {@link ISolution}s to the specified {@link PrintWriter}.
*
* @param writer The {@link PrintWriter} where the field should be written to.
* @param header The header used to specify the field.
* @param solutions The {@link ISolution}s to be written.
*/
private void writeField( final PrintWriter writer,
final String header,
final ISolution[] solutions ) {
if ( ( solutions == null ) || ( solutions.length == 0 ) ) {
writeField( writer, header, NA_STRING );
} else {
String[] sols = new String[ solutions.length ];
for ( int i = 0 ; i < sols.length ; i++ ) {
sols[i] = String.format( SOLUTION_FORMAT, solutions[i].getDescription(), solutions[i].getID() );
}
writeField( writer, header, sols );
}
}
/**
* Write the specified {@link String} to the specified {@link PrintWriter}.
*
* @param writer The {@link PrintWriter} where the field should be written to.
* @param header The header used to specify the field.
* @param content The {@link String} to be written.
*/
private void writeField( final PrintWriter writer,
final String header,
final String content ) {
if ( ( content == null ) || ( content.length() == 0 ) ) {
writeField( writer, header, NA_STRING );
} else {
writeField( writer, header, new String[] { content } );
}
}
/**
* Write the specified {@link String}s to the specified {@link PrintWriter}.
*
* @param writer The {@link PrintWriter} where the field should be written to.
* @param header The header used to specify the field.
* @param content The {@link String}s to be written.
*/
private void writeField( final PrintWriter writer,
final String header,
final String[] content ) {
if ( ( content == null ) || ( content.length == 0 ) ) {
writeField( writer, header, NA_STRING );
} else {
writer.println( header + HEADER_PREFIX );
for ( String s : content ) {
writer.println( FIELD_PREFIX + s );
}
writer.println();
}
}
}