package org.jabref.gui.errorconsole;
import java.io.IOException;
import java.net.URISyntaxException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import javafx.beans.property.ListProperty;
import javafx.beans.property.ReadOnlyListWrapper;
import javafx.collections.ObservableList;
import org.jabref.gui.AbstractViewModel;
import org.jabref.gui.ClipBoardManager;
import org.jabref.gui.DialogService;
import org.jabref.gui.MappedList;
import org.jabref.gui.desktop.JabRefDesktop;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.logging.LogMessages;
import org.jabref.logic.util.BuildInfo;
import org.jabref.logic.util.OS;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.client.utils.URIBuilder;
import org.apache.logging.log4j.core.LogEvent;
public class ErrorConsoleViewModel extends AbstractViewModel {
private static final Log LOGGER = LogFactory.getLog(ErrorConsoleViewModel.class);
private final DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
private final Date date = new Date();
private final DialogService dialogService;
private final ClipBoardManager clipBoardManager;
private final BuildInfo buildInfo;
private final ListProperty<LogEventViewModel> allMessagesData;
public ErrorConsoleViewModel(DialogService dialogService, ClipBoardManager clipBoardManager, BuildInfo buildInfo) {
this.dialogService = Objects.requireNonNull(dialogService);
this.clipBoardManager = Objects.requireNonNull(clipBoardManager);
this.buildInfo = Objects.requireNonNull(buildInfo);
ObservableList<LogEventViewModel> eventViewModels = new MappedList<>(LogMessages.getInstance().getMessages(), LogEventViewModel::new);
allMessagesData = new ReadOnlyListWrapper<>(eventViewModels);
}
public ListProperty<LogEventViewModel> allMessagesDataProperty() {
return this.allMessagesData;
}
/**
* Concatenates the formatted message of the given {@link LogEvent}s by using the a new line separator.
*
* @return all messages as String
*/
private String getLogMessagesAsString(List<LogEventViewModel> messages) {
return messages.stream()
.map(LogEventViewModel::getDetailedText)
.collect(Collectors.joining(OS.NEWLINE));
}
/**
* Copies the whole log to the clipboard
*/
public void copyLog() {
copyLog(allMessagesData);
}
/**
* Copies the given list of {@link LogEvent}s to the clipboard.
*/
public void copyLog(List<LogEventViewModel> messages) {
if (messages.isEmpty()) {
return;
}
clipBoardManager.setClipboardContents(getLogMessagesAsString(messages));
dialogService.notify(Localization.lang("Log copied to clipboard."));
}
/**
* Clears the current log
*/
public void clearLog() {
LogMessages.getInstance().clear();
}
/**
* Opens a new issue on GitHub and copies log to clipboard.
*/
public void reportIssue() {
try {
String issueTitle = "Automatic Bug Report - " + dateFormat.format(date);
// system info
String systemInfo = String.format("JabRef %s%n%s %s %s %nJava %s", buildInfo.getVersion(), BuildInfo.OS,
BuildInfo.OS_VERSION, BuildInfo.OS_ARCH, BuildInfo.JAVA_VERSION);
// steps to reproduce
String howToReproduce = "Steps to reproduce:\n\n1. ...\n2. ...\n3. ...";
// log messages
String issueDetails = "<details>\n" + "<summary>" + "Detail information:" + "</summary>\n\n```\n"
+ getLogMessagesAsString(allMessagesData) + "\n```\n\n</details>";
clipBoardManager.setClipboardContents(issueDetails);
// bug report body
String issueBody = systemInfo + "\n\n" + howToReproduce + "\n\n" + "Paste your log details here.";
dialogService.notify(Localization.lang("Issue on GitHub successfully reported."));
dialogService.showInformationDialogAndWait(Localization.lang("Issue report successful"),
Localization.lang("Your issue was reported in your browser.") + "\n" +
Localization.lang("The log and exception information was copied to your clipboard.") + " " +
Localization.lang("Please paste this information (with Ctrl+V) in the issue description.") + "\n" +
Localization.lang("Please also add all steps to reproduce this issue, if possible."));
URIBuilder uriBuilder = new URIBuilder()
.setScheme("https").setHost("github.com")
.setPath("/JabRef/jabref/issues/new")
.setParameter("title", issueTitle)
.setParameter("body", issueBody);
JabRefDesktop.openBrowser(uriBuilder.build().toString());
} catch (IOException | URISyntaxException e) {
LOGGER.error(e);
}
}
}