mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-10 13:18:05 +08:00
Merge remote-tracking branch 'origin/GP-1-dragonmacher-help-validation-tweak'
This commit is contained in:
@@ -32,20 +32,20 @@ import javax.swing.UIManager;
|
||||
|
||||
import docking.ComponentProvider;
|
||||
import docking.action.DockingActionIf;
|
||||
import generic.concurrent.GThreadPool;
|
||||
import generic.util.WindowUtilities;
|
||||
import ghidra.util.*;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskLauncher;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import resources.ResourceManager;
|
||||
import utilities.util.reflection.ReflectionUtilities;
|
||||
|
||||
/**
|
||||
* Class that uses JavaHelp browser to show context sensitive help.
|
||||
*
|
||||
*
|
||||
* <p>Note: this manager will validate all registered help when in development mode. In order
|
||||
* to catch items that have not registered help at all, we rely on those items to register a
|
||||
* to catch items that have not registered help at all, we rely on those items to register a
|
||||
* default {@link HelpLocation} that will get flagged as invalid. Examples of this usage are
|
||||
* the {@link DockingActionIf} and the {@link ComponentProvider} base classes.
|
||||
*/
|
||||
@@ -78,7 +78,7 @@ public class HelpManager implements HelpService {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
*
|
||||
* @param url url for the main HelpSet file for the application.
|
||||
* @throws HelpSetException if HelpSet could not be created
|
||||
*/
|
||||
@@ -104,7 +104,7 @@ public class HelpManager implements HelpService {
|
||||
|
||||
/**
|
||||
* Add the help set for the given URL.
|
||||
*
|
||||
*
|
||||
* @param url url for the HelpSet (.hs) file
|
||||
* @param classLoader the help classloader that knows how to find help modules in the classpath
|
||||
* @throws HelpSetException if the help set could not be created from the given URL.
|
||||
@@ -160,8 +160,8 @@ public class HelpManager implements HelpService {
|
||||
}
|
||||
|
||||
// Implementation Note: the same object can have different help registered. For example,
|
||||
// DockingActions do this as part of their construction process.
|
||||
// These actions will register a default help location and then
|
||||
// DockingActions do this as part of their construction process.
|
||||
// These actions will register a default help location and then
|
||||
// subclasses may change that location. We always use the most
|
||||
// recently registered action.
|
||||
helpLocations.put(helpObject, location);
|
||||
@@ -188,6 +188,7 @@ public class HelpManager implements HelpService {
|
||||
|
||||
/**
|
||||
* Returns the master help set (the one into which all other help sets are merged).
|
||||
* @return the help set
|
||||
*/
|
||||
public GHelpSet getMasterHelpSet() {
|
||||
return mainHS;
|
||||
@@ -195,10 +196,10 @@ public class HelpManager implements HelpService {
|
||||
|
||||
/**
|
||||
* Display the help page for the given URL. This is a specialty method for displaying
|
||||
* help when a specific file is desired, like an introduction page. Showing help for
|
||||
* objects within the system is accomplished by calling
|
||||
* help when a specific file is desired, like an introduction page. Showing help for
|
||||
* objects within the system is accomplished by calling
|
||||
* {@link #showHelp(Object, boolean, Component)}.
|
||||
*
|
||||
*
|
||||
* @param url the URL to display
|
||||
* @see #showHelp(Object, boolean, Component)
|
||||
*/
|
||||
@@ -400,7 +401,7 @@ public class HelpManager implements HelpService {
|
||||
((DefaultHelpBroker) mainHB).setActivationWindow(owner);
|
||||
}
|
||||
|
||||
// make sure we are visible before we set data (prevents bugs in JavaHelp)
|
||||
// make sure we are visible before we set data (prevents bugs in JavaHelp)
|
||||
mainHB.setDisplayed(true);
|
||||
|
||||
if (!wasDisplayed) {
|
||||
@@ -443,21 +444,20 @@ public class HelpManager implements HelpService {
|
||||
return;
|
||||
}
|
||||
|
||||
TaskLauncher.launchNonModal("Validating Help", monitor -> {
|
||||
try {
|
||||
printBadHelp(monitor);
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
// user cancelled; just exit
|
||||
}
|
||||
});
|
||||
GThreadPool.runAsync(Swing.GSWING_THREAD_POOL_NAME, this::doPrintBadHelp);
|
||||
}
|
||||
|
||||
private void printBadHelp(TaskMonitor monitor) throws CancelledException {
|
||||
private void doPrintBadHelp() {
|
||||
|
||||
Map<Object, HelpLocation> badHelp = getInvalidHelpLocations(monitor);
|
||||
if (badHelp.isEmpty()) {
|
||||
return;
|
||||
Map<Object, HelpLocation> badHelp;
|
||||
try {
|
||||
badHelp = getInvalidHelpLocations(TaskMonitor.DUMMY);
|
||||
if (badHelp.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
return; // user cancelled
|
||||
}
|
||||
|
||||
StringBuilder buffy = new StringBuilder();
|
||||
@@ -474,7 +474,6 @@ public class HelpManager implements HelpService {
|
||||
throws CancelledException {
|
||||
|
||||
Map<Object, HelpLocation> map = new WeakHashMap<>();
|
||||
|
||||
Map<Object, HelpLocation> helpLocationsCopy = copyHelpLocations();
|
||||
monitor.initialize(helpLocationsCopy.size());
|
||||
Set<Entry<Object, HelpLocation>> entries = helpLocationsCopy.entrySet();
|
||||
@@ -493,7 +492,7 @@ public class HelpManager implements HelpService {
|
||||
}
|
||||
|
||||
private Map<Object, HelpLocation> copyHelpLocations() {
|
||||
// we must copy the help locations, since we are in a background thread and the
|
||||
// we must copy the help locations, since we are in a background thread and the
|
||||
// locations map is frequently updated by the Swing thread
|
||||
return Swing.runNow(() -> new HashMap<>(helpLocations));
|
||||
}
|
||||
@@ -501,9 +500,9 @@ public class HelpManager implements HelpService {
|
||||
//
|
||||
// Warning!
|
||||
// This code has timing implications. DockingActions register themselves with the help
|
||||
// system as part of their construction. At that point, they are not usually fully
|
||||
// system as part of their construction. At that point, they are not usually fully
|
||||
// constructed, as most clients will use the newly constructed action to set the various
|
||||
// toolbar/menu/popup data elements. For us to know if the action is really only for
|
||||
// toolbar/menu/popup data elements. For us to know if the action is really only for
|
||||
// keybinding purposes, we have to do this check after the action is fully constructed.
|
||||
//
|
||||
private boolean isKeybindingOnly(Object helpee) {
|
||||
@@ -630,7 +629,7 @@ public class HelpManager implements HelpService {
|
||||
}
|
||||
|
||||
// Note: not sure if we ever need to merge again after the initial load. If so, then
|
||||
// this flag doesn't make sense. However, as of this writing, we do not discover
|
||||
// this flag doesn't make sense. However, as of this writing, we do not discover
|
||||
// new help sets on the fly.
|
||||
hasMergedHelpSets = true;
|
||||
helpSetsPendingMerge.clear();
|
||||
@@ -657,7 +656,7 @@ public class HelpManager implements HelpService {
|
||||
/**
|
||||
* Create a new help set for the given url, if one does
|
||||
* not already exist.
|
||||
* @param classLoader
|
||||
* @param classLoader the class loader
|
||||
*/
|
||||
private HelpSet createHelpSet(URL url, GHelpClassLoader classLoader) throws HelpSetException {
|
||||
if (!urlToHelpSets.containsKey(url)) {
|
||||
@@ -668,7 +667,7 @@ public class HelpManager implements HelpService {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Set the color resources on the JEditorPane for selection so that
|
||||
* you can see the highlights when you do a search in the JavaHelp.
|
||||
*/
|
||||
|
||||
@@ -31,17 +31,17 @@ import ghidra.util.SystemUtilities;
|
||||
* <p>
|
||||
* The simple behavior for when new tasks are submitted:<br>
|
||||
* 1) If there any idle threads, use that thread.<br>
|
||||
* 2) If all existing threads are busy and the number of threads is less than max threads, add a
|
||||
* 2) If all existing threads are busy and the number of threads is less than max threads, add a
|
||||
* new thread and use it.<br>
|
||||
* 3) if all threads are busy and there are max number of threads, queue the item until a thread
|
||||
* becomes free.<br>
|
||||
* <p>
|
||||
* The simple behavior for when tasks are completed by a thread:<br>
|
||||
* 1) If there are tasks in the queue, start processing a new item in the newly freed thread.<br>
|
||||
* 2) if there are more threads that min threads, allow this thread to die if no new
|
||||
* 2) if there are more threads that min threads, allow this thread to die if no new
|
||||
* jobs arrive before
|
||||
* the "KEEP ALIVE" time expires which is currently 15 seconds.<br>
|
||||
* 3) if there are min threads or less, allow this thread to wait forever for a new job
|
||||
* 3) if there are min threads or less, allow this thread to wait forever for a new job
|
||||
* to arrive.<br>
|
||||
*/
|
||||
public class GThreadPool {
|
||||
@@ -76,6 +76,18 @@ public class GThreadPool {
|
||||
return threadPool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the given runnable in a background thread using a shared thread pool of the given name.
|
||||
* @param poolName the thread pool name
|
||||
* @param r the runnable
|
||||
* @return the future
|
||||
*/
|
||||
public static CompletableFuture<Void> runAsync(String poolName, Runnable r) {
|
||||
GThreadPool pool = getSharedThreadPool(poolName);
|
||||
Executor ex = pool.getExecutor();
|
||||
return CompletableFuture.runAsync(r, ex);
|
||||
}
|
||||
|
||||
private GThreadPool(String name) {
|
||||
this.name = name;
|
||||
executor = new GThreadPoolExecutor();
|
||||
@@ -157,7 +169,7 @@ public class GThreadPool {
|
||||
|
||||
/**
|
||||
* Returns true if this is not a shared thread pool.
|
||||
*
|
||||
*
|
||||
* @return true if this is not a shared thread pool.
|
||||
*/
|
||||
public boolean isPrivate() {
|
||||
@@ -166,12 +178,12 @@ public class GThreadPool {
|
||||
|
||||
/**
|
||||
* Returns the {@link Executor} used by this thread pool.
|
||||
*
|
||||
* <P>Note: normal usage of this thread pool contraindicates accessing the executor of
|
||||
*
|
||||
* <P>Note: normal usage of this thread pool contraindicates accessing the executor of
|
||||
* this pool. For managing your own jobs, you should use the method on this class directly.
|
||||
* The intent of this method is to provide access to the executor so that it may be
|
||||
* The intent of this method is to provide access to the executor so that it may be
|
||||
* passed to other asynchronous APIs, such as the {@link CompletableFuture}.
|
||||
*
|
||||
*
|
||||
* @return the executor
|
||||
*/
|
||||
public Executor getExecutor() {
|
||||
@@ -180,7 +192,7 @@ public class GThreadPool {
|
||||
|
||||
//==================================================================================================
|
||||
// Inner Classes
|
||||
//==================================================================================================
|
||||
//==================================================================================================
|
||||
|
||||
private class GThreadPoolExecutor extends ThreadPoolExecutor {
|
||||
private volatile int maxThreadCount = SystemUtilities.getDefaultThreadPoolSize();
|
||||
|
||||
Reference in New Issue
Block a user