/*
* This file is part of the Illarion project.
*
* Copyright © 2015 - Illarion e.V.
*
* Illarion is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Illarion 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.
*/
package illarion.common.bug;
import illarion.common.util.AppIdent;
import org.jetbrains.annotations.Contract;
import javax.annotation.Nonnull;
/**
* This class is used to wrap the data that is collected about one crash into a
* single object and prepare the value set for later usage. The object is
* immutable. So once the values are set, they can't be changed anymore.
*
* @author Martin Karing <nitram@illarion.org>
*/
public final class CrashData {
/**
* The string that is used to introduce a caused part of the crash data.
*/
private static final String CAUSED = "Caused by: ";
/**
* The newline string that is used to create the backtrace.
*/
private static final String NL = "\n";
/**
* The tab string that is used to create the backtrace.
*/
private static final String TAB = "\t";
/**
* The human readable description of the problem
*/
@Nonnull
private final String description;
/**
* The exception that caused the crash.
*/
@Nonnull
private final String exception;
/**
* The name of the exception class.
*/
@Nonnull
private final String exceptionName;
/**
* The application identifier for the application that crashed.
*/
@Nonnull
private final AppIdent applicationIdentifier;
/**
* The thread the crash happened in.
*/
@Nonnull
private final String threadName;
/**
* The name of the mantis project this report is supposed to end up in.
*/
@Nonnull
private final String mantisProject;
/**
* The constructor that collects all data for such a crash data object.
*
* @param appIdent the application identifier
* @param problemDescription the human readable description of the error.
* This is not send to the server, its just displayed
* @param crashThread the thread that crashed
* @param crashException the exception that caused the crash
*/
public CrashData(
@Nonnull AppIdent appIdent,
@Nonnull String mantisProject,
@Nonnull String problemDescription,
@Nonnull Thread crashThread,
@Nonnull Throwable crashException) {
applicationIdentifier = appIdent;
threadName = crashThread.getName();
this.mantisProject = mantisProject;
StringBuilder builder = new StringBuilder();
Throwable current = crashException;
while (current != null) {
builder.append(current.getClass().getName());
builder.append('(');
builder.append('"');
builder.append(current.getMessage());
builder.append('"');
builder.append(')');
builder.append(NL);
StackTraceElement[] backtrace = current.getStackTrace();
for (StackTraceElement element : backtrace) {
builder.append(TAB);
builder.append(element);
builder.append(NL);
}
current = current.getCause();
if (current != null) {
builder.append(CAUSED);
}
}
exception = builder.toString();
description = problemDescription;
exceptionName = crashException.getClass().getSimpleName();
}
/**
* This method creates a string to identify the operation system.
*
* @return the string to identify the operation system
*/
@Nonnull
static String getOSName() {
return System.getProperty("os.name") + ' ' + System.getProperty("os.version") + ' ' +
System.getProperty("os.arch");
}
/**
* Get the identifier of the application.
*
* @return the identifier of the application
*/
@Nonnull
@Contract(pure = true)
AppIdent getApplicationIdentifier() {
return applicationIdentifier;
}
/**
* Get the description of the problem
*
* @return the description of the problem
*/
@Nonnull
@Contract(pure = true)
String getDescription() {
return description;
}
/**
* The simple name of the exception.
*
* @return the simple name of the exception
*/
@Nonnull
@Contract(pure = true)
String getExceptionName() {
return exceptionName;
}
/**
* Get the full stack backtrace of the crash.
*
* @return the stack backtrace
*/
@Nonnull
@Contract(pure = true)
String getStackBacktrace() {
return exception;
}
/**
* Get the name of the thread the crash happened in.
*
* @return the name of the thread that crashed
*/
@Nonnull
@Contract(pure = true)
String getThreadName() {
return threadName;
}
@Nonnull
@Contract(pure = true)
String getMantisProject() {
return mantisProject;
}
}