mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 19:42:36 +02:00
GT-3610 - Updated the analysis log message dialog to not stretch the
entirety of the screen; fixed flax in MessageLog
This commit is contained in:
parent
9e568c9de3
commit
d52c417327
11 changed files with 134 additions and 115 deletions
|
@ -44,6 +44,7 @@ public abstract class AbstractDemanglerAnalyzer extends AbstractAnalyzer {
|
||||||
public AbstractDemanglerAnalyzer(String name, String description) {
|
public AbstractDemanglerAnalyzer(String name, String description) {
|
||||||
super(name, description, AnalyzerType.BYTE_ANALYZER);
|
super(name, description, AnalyzerType.BYTE_ANALYZER);
|
||||||
setPriority(AnalysisPriority.DATA_TYPE_PROPOGATION.before().before().before());
|
setPriority(AnalysisPriority.DATA_TYPE_PROPOGATION.before().before().before());
|
||||||
|
setSupportsOneTimeAnalysis();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -58,7 +59,7 @@ public abstract class AbstractDemanglerAnalyzer extends AbstractAnalyzer {
|
||||||
|
|
||||||
DemanglerOptions options = getOptions();
|
DemanglerOptions options = getOptions();
|
||||||
if (!validateOptions(options, log)) {
|
if (!validateOptions(options, log)) {
|
||||||
log.error(getName(), "Invalid demangler options--cannot demangle");
|
log.appendMsg(getName(), "Invalid demangler options--cannot demangle");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -849,9 +849,6 @@ public class AutoAnalysisManager implements DomainObjectListener, DomainObjectCl
|
||||||
for (AutoAnalysisManagerListener listener : listeners) {
|
for (AutoAnalysisManagerListener listener : listeners) {
|
||||||
listener.analysisEnded(this);
|
listener.analysisEnded(this);
|
||||||
}
|
}
|
||||||
if (log.getMsgCount() > 0) {
|
|
||||||
Msg.info(AutoAnalysisManager.class, log.toString());
|
|
||||||
}
|
|
||||||
log.clear();
|
log.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -319,9 +319,16 @@ public class AutoAnalysisPlugin extends Plugin implements AutoAnalysisManagerLis
|
||||||
@Override
|
@Override
|
||||||
public void analysisEnded(AutoAnalysisManager manager) {
|
public void analysisEnded(AutoAnalysisManager manager) {
|
||||||
MessageLog log = manager.getMessageLog();
|
MessageLog log = manager.getMessageLog();
|
||||||
if (log.getMsgCount() > 0) {
|
if (log.hasMessages()) {
|
||||||
|
|
||||||
|
log.write(AutoAnalysisManager.class, "Analysis Log Messages");
|
||||||
|
|
||||||
|
String shortMessage = "There were warnings/errors issued during analysis.";
|
||||||
|
String detailedMessage =
|
||||||
|
"(These messages are also written to the application log file)\n\n" +
|
||||||
|
log.toString();
|
||||||
MultiLineMessageDialog dialog = new MultiLineMessageDialog("Auto Analysis Summary",
|
MultiLineMessageDialog dialog = new MultiLineMessageDialog("Auto Analysis Summary",
|
||||||
"There were warnings/errors issued during analysis.", log.toString(),
|
shortMessage, detailedMessage,
|
||||||
MultiLineMessageDialog.WARNING_MESSAGE, false);//modal?
|
MultiLineMessageDialog.WARNING_MESSAGE, false);//modal?
|
||||||
DockingWindowManager.showDialog(null, dialog);
|
DockingWindowManager.showDialog(null, dialog);
|
||||||
}
|
}
|
||||||
|
|
|
@ -499,9 +499,7 @@ public class ExporterDialog extends DialogComponentProvider implements AddressFa
|
||||||
resultsBuffer.append("Format: " + exporter.getName() + "\n\n");
|
resultsBuffer.append("Format: " + exporter.getName() + "\n\n");
|
||||||
|
|
||||||
MessageLog log = exporter.getMessageLog();
|
MessageLog log = exporter.getMessageLog();
|
||||||
if (log != null) {
|
|
||||||
resultsBuffer.append(log.toString());
|
resultsBuffer.append(log.toString());
|
||||||
}
|
|
||||||
|
|
||||||
HelpLocation helpLocation = new HelpLocation(GenericHelpTopics.ABOUT, "About_Program");
|
HelpLocation helpLocation = new HelpLocation(GenericHelpTopics.ABOUT, "About_Program");
|
||||||
|
|
||||||
|
|
|
@ -145,9 +145,11 @@ public class ImportBatchTask extends Task {
|
||||||
Object consumer = new Object();
|
Object consumer = new Object();
|
||||||
try {
|
try {
|
||||||
MessageLog messageLog = new MessageLog();
|
MessageLog messageLog = new MessageLog();
|
||||||
List<DomainObject> importedObjects = loadSpec.getLoader().load(byteProvider,
|
List<DomainObject> importedObjects = loadSpec.getLoader()
|
||||||
|
.load(byteProvider,
|
||||||
fixupProjectFilename(destInfo.second), destInfo.first, loadSpec,
|
fixupProjectFilename(destInfo.second), destInfo.first, loadSpec,
|
||||||
getOptionsFor(batchLoadConfig, loadSpec, byteProvider), messageLog, consumer,
|
getOptionsFor(batchLoadConfig, loadSpec, byteProvider), messageLog,
|
||||||
|
consumer,
|
||||||
monitor);
|
monitor);
|
||||||
|
|
||||||
// TODO: accumulate batch results
|
// TODO: accumulate batch results
|
||||||
|
@ -163,7 +165,7 @@ public class ImportBatchTask extends Task {
|
||||||
|
|
||||||
Msg.info(this, "Imported " + destInfo.first + "/ " + destInfo.second + ", " +
|
Msg.info(this, "Imported " + destInfo.first + "/ " + destInfo.second + ", " +
|
||||||
totalAppsImported + " of " + totalEnabledApps);
|
totalAppsImported + " of " + totalEnabledApps);
|
||||||
if (messageLog.getMsgCount() > 0) {
|
if (messageLog.hasMessages()) {
|
||||||
Msg.info(this, "Additional info:\n" + messageLog.toString());
|
Msg.info(this, "Additional info:\n" + messageLog.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,8 @@ public class AndroidProjectCreator {
|
||||||
public void create(TaskMonitor monitor) throws IOException, CancelledException {
|
public void create(TaskMonitor monitor) throws IOException, CancelledException {
|
||||||
createEclipseProjectDirectories();
|
createEclipseProjectDirectories();
|
||||||
|
|
||||||
try (ZipFileSystem fs = FileSystemService.getInstance().mountSpecificFileSystem(
|
try (ZipFileSystem fs = FileSystemService.getInstance()
|
||||||
|
.mountSpecificFileSystem(
|
||||||
apkFile.getFSRL(), ZipFileSystem.class, monitor)) {
|
apkFile.getFSRL(), ZipFileSystem.class, monitor)) {
|
||||||
List<GFile> listing = fs.getListing(null);
|
List<GFile> listing = fs.getListing(null);
|
||||||
processListing(eclipseProjectDirectory, listing, monitor);
|
processListing(eclipseProjectDirectory, listing, monitor);
|
||||||
|
@ -163,7 +164,8 @@ public class AndroidProjectCreator {
|
||||||
|
|
||||||
private void processDex(File outputDirectory, GFile dexFile, TaskMonitor monitor)
|
private void processDex(File outputDirectory, GFile dexFile, TaskMonitor monitor)
|
||||||
throws IOException, CancelledException {
|
throws IOException, CancelledException {
|
||||||
try (DexToJarFileSystem fs = FileSystemService.getInstance().mountSpecificFileSystem(
|
try (DexToJarFileSystem fs = FileSystemService.getInstance()
|
||||||
|
.mountSpecificFileSystem(
|
||||||
dexFile.getFSRL(), DexToJarFileSystem.class, monitor)) {
|
dexFile.getFSRL(), DexToJarFileSystem.class, monitor)) {
|
||||||
GFile jarFile = fs.getJarFile();
|
GFile jarFile = fs.getJarFile();
|
||||||
processJar(srcDirectory, jarFile.getFSRL(), monitor);
|
processJar(srcDirectory, jarFile.getFSRL(), monitor);
|
||||||
|
@ -176,7 +178,7 @@ public class AndroidProjectCreator {
|
||||||
JarDecompiler decompiler = new JarDecompiler(jarFile, outputDirectory);
|
JarDecompiler decompiler = new JarDecompiler(jarFile, outputDirectory);
|
||||||
decompiler.decompile(monitor);
|
decompiler.decompile(monitor);
|
||||||
|
|
||||||
if (decompiler.getLog().getMsgCount() > 0) {
|
if (decompiler.getLog().hasMessages()) {
|
||||||
log.copyFrom(decompiler.getLog());
|
log.copyFrom(decompiler.getLog());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,7 +201,8 @@ public class AndroidProjectCreator {
|
||||||
private void processXML(File outputDirectory, GFile containerFile, TaskMonitor monitor)
|
private void processXML(File outputDirectory, GFile containerFile, TaskMonitor monitor)
|
||||||
throws CancelledException {
|
throws CancelledException {
|
||||||
|
|
||||||
try (AndroidXmlFileSystem fs = FileSystemService.getInstance().mountSpecificFileSystem(
|
try (AndroidXmlFileSystem fs = FileSystemService.getInstance()
|
||||||
|
.mountSpecificFileSystem(
|
||||||
containerFile.getFSRL(), AndroidXmlFileSystem.class, monitor)) {
|
containerFile.getFSRL(), AndroidXmlFileSystem.class, monitor)) {
|
||||||
GFile xmlFile = fs.getPayloadFile();
|
GFile xmlFile = fs.getPayloadFile();
|
||||||
copyStream(fs.getInputStream(xmlFile, monitor), outputDirectory,
|
copyStream(fs.getInputStream(xmlFile, monitor), outputDirectory,
|
||||||
|
|
|
@ -128,7 +128,7 @@ public class FileFormatsPlugin extends Plugin implements FrontEndable {
|
||||||
new AndroidProjectCreator(refdFile.file, outputDirectory);
|
new AndroidProjectCreator(refdFile.file, outputDirectory);
|
||||||
creator.create(monitor);
|
creator.create(monitor);
|
||||||
|
|
||||||
if (creator.getLog().getMsgCount() > 0) {
|
if (creator.getLog().hasMessages()) {
|
||||||
Msg.showInfo(this, getTool().getActiveWindow(), "Export to Eclipse Project",
|
Msg.showInfo(this, getTool().getActiveWindow(), "Export to Eclipse Project",
|
||||||
creator.getLog().toString());
|
creator.getLog().toString());
|
||||||
}
|
}
|
||||||
|
@ -194,7 +194,7 @@ public class FileFormatsPlugin extends Plugin implements FrontEndable {
|
||||||
new JarDecompiler(jarFSRL, outputDirectory);
|
new JarDecompiler(jarFSRL, outputDirectory);
|
||||||
decompiler.decompile(monitor);
|
decompiler.decompile(monitor);
|
||||||
|
|
||||||
if (decompiler.getLog().getMsgCount() > 0) {
|
if (decompiler.getLog().hasMessages()) {
|
||||||
Msg.showInfo(this, gTree,
|
Msg.showInfo(this, gTree,
|
||||||
"Decompiling Jar " + jarFSRL.getName(),
|
"Decompiling Jar " + jarFSRL.getName(),
|
||||||
decompiler.getLog().toString());
|
decompiler.getLog().toString());
|
||||||
|
|
|
@ -133,7 +133,7 @@ public class GnuDemanglerAnalyzer extends AbstractDemanglerAnalyzer {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
log.error(getName(), "Invalid options for GNU dangler '" + demanglerName +
|
log.appendMsg(getName(), "Invalid options for GNU dangler '" + demanglerName +
|
||||||
"': " + applicationArguments);
|
"': " + applicationArguments);
|
||||||
log.appendException(e);
|
log.appendException(e);
|
||||||
}
|
}
|
||||||
|
@ -148,7 +148,7 @@ public class GnuDemanglerAnalyzer extends AbstractDemanglerAnalyzer {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
log.error(getName(),
|
log.appendMsg(getName(),
|
||||||
"Invalid options for GNU dangler '" + deprecatedName + "': " +
|
"Invalid options for GNU dangler '" + deprecatedName + "': " +
|
||||||
applicationArguments);
|
applicationArguments);
|
||||||
log.appendException(e);
|
log.appendException(e);
|
||||||
|
|
|
@ -108,7 +108,7 @@ class LoadPdbTask extends Task {
|
||||||
Msg.showError(getClass(), null, "Load PDB Failed", message, t);
|
Msg.showError(getClass(), null, "Load PDB Failed", message, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (log.getMsgCount() > 0) {
|
if (log.hasMessages()) {
|
||||||
MultiLineMessageDialog dialog = new MultiLineMessageDialog("Load PDB File",
|
MultiLineMessageDialog dialog = new MultiLineMessageDialog("Load PDB File",
|
||||||
"There were warnings/errors loading the PDB file.", log.toString(),
|
"There were warnings/errors loading the PDB file.", log.toString(),
|
||||||
MultiLineMessageDialog.WARNING_MESSAGE, false);
|
MultiLineMessageDialog.WARNING_MESSAGE, false);
|
||||||
|
|
|
@ -104,34 +104,41 @@ public class MultiLineMessageDialog extends DialogComponentProvider {
|
||||||
// In this case, we are also inserting a <body> that specifies the font-family
|
// In this case, we are also inserting a <body> that specifies the font-family
|
||||||
// to get us back to the same font the rest of the GUI is using.
|
// to get us back to the same font the rest of the GUI is using.
|
||||||
|
|
||||||
JTextPane textpane = new JTextPane();
|
JTextPane textPane = new JTextPane();
|
||||||
String fontfamily = textpane.getFont().getFamily();
|
String fontfamily = textPane.getFont().getFamily();
|
||||||
detailedMessage = "<html><body style=\"font-family: " + fontfamily + "\">" +
|
detailedMessage = "<html><body style=\"font-family: " + fontfamily + "\">" +
|
||||||
detailedMessage.substring(6);
|
detailedMessage.substring(6);
|
||||||
|
|
||||||
// Set the textpane to not auto-scroll to bottom when adding text
|
// Set the textpane to not auto-scroll to bottom when adding text
|
||||||
DefaultCaret caret = (DefaultCaret) textpane.getCaret();
|
DefaultCaret caret = (DefaultCaret) textPane.getCaret();
|
||||||
caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
|
caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
|
||||||
|
|
||||||
textpane.setContentType("text/html");
|
textPane.setContentType("text/html");
|
||||||
textpane.setText(detailedMessage);
|
textPane.setText(detailedMessage);
|
||||||
textpane.setEditable(false);
|
textPane.setEditable(false);
|
||||||
|
|
||||||
DockingUtils.setTransparent(textpane);
|
DockingUtils.setTransparent(textPane);
|
||||||
JScrollPane scrollPane = new JScrollPane(textpane);
|
JScrollPane scrollPane = new JScrollPane(textPane);
|
||||||
DockingUtils.setTransparent(scrollPane);
|
DockingUtils.setTransparent(scrollPane);
|
||||||
scrollPane.setBorder(BorderFactory.createEmptyBorder());
|
scrollPane.setBorder(BorderFactory.createEmptyBorder());
|
||||||
workPanel.add(scrollPane, BorderLayout.CENTER);
|
workPanel.add(scrollPane, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
// note: this must be done after adding the text component to the scroll pane
|
||||||
|
// (seems like the scroll pane is changing the border)
|
||||||
|
textPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
JTextArea textarea = new JTextArea(detailedMessage);
|
JTextArea textArea = new JTextArea(detailedMessage);
|
||||||
textarea.setEditable(false);
|
textArea.setEditable(false);
|
||||||
|
|
||||||
DockingUtils.setTransparent(textarea);
|
DockingUtils.setTransparent(textArea);
|
||||||
JScrollPane scrollPane = new JScrollPane(textarea);
|
JScrollPane scrollPane = new JScrollPane(textArea);
|
||||||
DockingUtils.setTransparent(scrollPane);
|
DockingUtils.setTransparent(scrollPane);
|
||||||
scrollPane.setBorder(BorderFactory.createEmptyBorder());
|
|
||||||
workPanel.add(scrollPane, BorderLayout.CENTER);
|
workPanel.add(scrollPane, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
// note: this must be done after adding the text component to the scroll pane
|
||||||
|
// (seems like the scroll pane is changing the border)
|
||||||
|
textArea.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
Icon icon = OptionDialog.getIconForMessageType(messageType);
|
Icon icon = OptionDialog.getIconForMessageType(messageType);
|
||||||
|
@ -147,10 +154,14 @@ public class MultiLineMessageDialog extends DialogComponentProvider {
|
||||||
setFocusComponent(okButton);
|
setFocusComponent(okButton);
|
||||||
setDefaultButton(okButton);
|
setDefaultButton(okButton);
|
||||||
setRememberSize(false);
|
setRememberSize(false);
|
||||||
|
|
||||||
|
// A somewhat arbitrary number to prevent the dialog from stretching across the screen
|
||||||
|
setPreferredSize(600, 300);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void okCallback() {
|
protected void okCallback() {
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,51 +15,41 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.util.importer;
|
package ghidra.app.util.importer;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.exception.AssertException;
|
import utilities.util.reflection.ReflectionUtilities;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple class to handle logging messages and exceptions. A maximum message count size
|
* A simple class to handle logging messages and exceptions. A maximum message count size
|
||||||
* constraint can be set to clip messages after a certain number, but still keep incrementing
|
* constraint can be set to clip messages after a certain number, but still keep incrementing
|
||||||
* a running total.
|
* a running total.
|
||||||
|
*
|
||||||
|
* <p>In addition to logging messages, clients can also set a status message. This message may
|
||||||
|
* later used as the primary error message when reporting to the user.
|
||||||
*/
|
*/
|
||||||
public class MessageLog {
|
public class MessageLog {
|
||||||
/**
|
/**
|
||||||
* The default number of messages to store before clipping
|
* The default number of messages to store before clipping
|
||||||
*/
|
*/
|
||||||
public final static int MAX_COUNT = 500;
|
private final static int MAX_COUNT = 500;
|
||||||
|
|
||||||
private StringBuffer buffer = new StringBuffer();
|
private List<String> messages = new ArrayList<>();
|
||||||
private int maxSize;
|
private int maxSize = MAX_COUNT;
|
||||||
private int count;
|
private int count;
|
||||||
private int pos = -1;
|
private String statusMsg = StringUtils.EMPTY;
|
||||||
private String statusMsg;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new message log using the default message count
|
|
||||||
*/
|
|
||||||
public MessageLog() {
|
|
||||||
this(MAX_COUNT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new message log using the specified message count
|
|
||||||
* @param maxSize the maximum number of messages
|
|
||||||
*/
|
|
||||||
public MessageLog(int maxSize) {
|
|
||||||
this.maxSize = maxSize;
|
|
||||||
clearStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies the contents of one message log into this one
|
* Copies the contents of one message log into this one
|
||||||
* @param log the log to copy from
|
* @param log the log to copy from
|
||||||
*/
|
*/
|
||||||
public void copyFrom(MessageLog log) {
|
public void copyFrom(MessageLog log) {
|
||||||
this.buffer = new StringBuffer(log.buffer);
|
for (String otherMessage : log.messages) {
|
||||||
this.maxSize = log.maxSize;
|
add(otherMessage);
|
||||||
this.count = log.count;
|
}
|
||||||
this.pos = log.pos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -67,7 +57,7 @@ public class MessageLog {
|
||||||
* @param message the message
|
* @param message the message
|
||||||
*/
|
*/
|
||||||
public void appendMsg(String message) {
|
public void appendMsg(String message) {
|
||||||
msg(message);
|
add(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,10 +68,10 @@ public class MessageLog {
|
||||||
*/
|
*/
|
||||||
public void appendMsg(String originator, String message) {
|
public void appendMsg(String originator, String message) {
|
||||||
if (originator == null) {
|
if (originator == null) {
|
||||||
msg(message);
|
add(message);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
msg(originator + "> " + message);
|
add(originator + "> " + message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +81,7 @@ public class MessageLog {
|
||||||
* @param message the message
|
* @param message the message
|
||||||
*/
|
*/
|
||||||
public void appendMsg(int lineNum, String message) {
|
public void appendMsg(int lineNum, String message) {
|
||||||
msg("Line #" + lineNum + " - " + message);
|
add("Line #" + lineNum + " - " + message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -99,31 +89,39 @@ public class MessageLog {
|
||||||
* @param t the exception to append to the log
|
* @param t the exception to append to the log
|
||||||
*/
|
*/
|
||||||
public void appendException(Throwable t) {
|
public void appendException(Throwable t) {
|
||||||
if (t instanceof NullPointerException || t instanceof AssertException) {
|
String asString = ReflectionUtilities.stackTraceToString(t);
|
||||||
Msg.error(this, "Exception appended to MessageLog", t);
|
add(asString);
|
||||||
}
|
|
||||||
else {
|
|
||||||
Msg.debug(this, "Exception appended to MessageLog", t);
|
|
||||||
}
|
|
||||||
String msg = t.toString();
|
|
||||||
msg(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the message count
|
* Readable method for appending error messages to the log.
|
||||||
* @return the message count
|
*
|
||||||
|
* <p>Currently does nothing different than {@link #appendMsg(String, String)}.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param originator the originator of the message
|
||||||
|
* @param message the message
|
||||||
|
* @deprecated use {@link #appendMsg(String)}
|
||||||
*/
|
*/
|
||||||
public int getMsgCount() {
|
@Deprecated
|
||||||
return count;
|
public void error(String originator, String message) {
|
||||||
|
appendMsg(originator, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if this log has messages
|
||||||
|
* @return true if this log has messages
|
||||||
|
*/
|
||||||
|
public boolean hasMessages() {
|
||||||
|
return count > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears all messages from this log and resets the count
|
* Clears all messages from this log and resets the count
|
||||||
*/
|
*/
|
||||||
public void clear() {
|
public void clear() {
|
||||||
buffer = new StringBuffer();
|
messages = new ArrayList<>();
|
||||||
count = 0;
|
count = 0;
|
||||||
pos = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -138,7 +136,7 @@ public class MessageLog {
|
||||||
* Clear status message
|
* Clear status message
|
||||||
*/
|
*/
|
||||||
public void clearStatus() {
|
public void clearStatus() {
|
||||||
statusMsg = "";
|
statusMsg = StringUtils.EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -151,39 +149,41 @@ public class MessageLog {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
if (count > maxSize) {
|
return toStringWithWarning();
|
||||||
if (pos > -1) {
|
|
||||||
buffer.delete(pos, buffer.length());
|
|
||||||
}
|
|
||||||
pos = buffer.length();
|
|
||||||
buffer.append("\n \n");
|
|
||||||
buffer.append("There were too many messages to display.\n");
|
|
||||||
buffer.append("" + (count - maxSize) + " messages have been truncated.");
|
|
||||||
buffer.append("\n \n");
|
|
||||||
}
|
|
||||||
return buffer.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void msg(String msg) {
|
|
||||||
if (msg == null || msg.length() == 0) {//discard if null...
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (count++ < maxSize) {
|
|
||||||
buffer.append(msg);
|
|
||||||
buffer.append("\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Readable method for appending error messages to the log.
|
* Writes this log's contents to the application log
|
||||||
*
|
* @param owner the owning class whose name will appear in the log message
|
||||||
* <p>Currently does nothing different than {@link #appendMsg(String, String)}.
|
* @param messageHeader the message header that will appear before the log messages
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param originator the originator of the message
|
|
||||||
* @param message the message
|
|
||||||
*/
|
*/
|
||||||
public void error(String originator, String message) {
|
public void write(Class<?> owner, String messageHeader) {
|
||||||
appendMsg(originator, message);
|
String header = StringUtils.defaultIfBlank(messageHeader, "Log Messages");
|
||||||
|
Msg.info(owner, header + '\n' + toStringWithWarning());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String toStringWithWarning() {
|
||||||
|
StringBuilder output = new StringBuilder();
|
||||||
|
if (count > maxSize) {
|
||||||
|
output.append('\n').append('\n');
|
||||||
|
output.append("There were too many messages to display.\n");
|
||||||
|
output.append((count - maxSize)).append(" messages have been truncated.");
|
||||||
|
output.append('\n').append('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String s : messages) {
|
||||||
|
output.append(s).append('\n');
|
||||||
|
}
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void add(String msg) {
|
||||||
|
if (StringUtils.isBlank(msg)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count++ < maxSize) {
|
||||||
|
messages.add(msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue