mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 10:19:23 +02:00
GP-155 - Help - fixed intermittent help build issue caused by map keys
using display text instead of the unique help item ID Closes #2443
This commit is contained in:
parent
ddf6db0eec
commit
7940f96c8c
5 changed files with 85 additions and 65 deletions
|
@ -42,13 +42,11 @@ public class OverlayHelpTree {
|
||||||
|
|
||||||
public OverlayHelpTree(TOCItemProvider tocItemProvider, LinkDatabase linkDatabase) {
|
public OverlayHelpTree(TOCItemProvider tocItemProvider, LinkDatabase linkDatabase) {
|
||||||
this.linkDatabase = linkDatabase;
|
this.linkDatabase = linkDatabase;
|
||||||
for (TOCItemExternal external : tocItemProvider.getTOCItemExternalsByDisplayMapping()
|
for (TOCItemExternal external : tocItemProvider.getExternalTocItemsById().values()) {
|
||||||
.values()) {
|
|
||||||
addExternalTOCItem(external);
|
addExternalTOCItem(external);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (TOCItemDefinition definition : tocItemProvider.getTOCItemDefinitionsByIDMapping()
|
for (TOCItemDefinition definition : tocItemProvider.getTocDefinitionsByID().values()) {
|
||||||
.values()) {
|
|
||||||
addSourceTOCItem(definition);
|
addSourceTOCItem(definition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,8 +169,16 @@ public class OverlayHelpTree {
|
||||||
OverlayNode newRootNode = new OverlayNode(null, rootItem);
|
OverlayNode newRootNode = new OverlayNode(null, rootItem);
|
||||||
buildChildren(newRootNode);
|
buildChildren(newRootNode);
|
||||||
|
|
||||||
|
//
|
||||||
|
// The parent to children map is cleared as nodes are created. The map is populated by
|
||||||
|
// adding any references to the 'parent' key as they are loaded from the help files.
|
||||||
|
// As we build nodes, starting at the root, will will create child nodes for those that
|
||||||
|
// reference the 'parent' key. If the map is empty, then it means we never built a
|
||||||
|
// node for the 'parent' key, which means we never found a help file containing the
|
||||||
|
// definition for that key.
|
||||||
|
//
|
||||||
if (!parentToChildrenMap.isEmpty()) {
|
if (!parentToChildrenMap.isEmpty()) {
|
||||||
throw new RuntimeException("Unresolved definitions in tree!");
|
throw new RuntimeException("Unresolved definitions in tree! - " + parentToChildrenMap);
|
||||||
}
|
}
|
||||||
rootNode = newRootNode;
|
rootNode = newRootNode;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,18 +15,25 @@
|
||||||
*/
|
*/
|
||||||
package help;
|
package help;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import help.validator.model.TOCItemDefinition;
|
import help.validator.model.TOCItemDefinition;
|
||||||
import help.validator.model.TOCItemExternal;
|
import help.validator.model.TOCItemExternal;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An interface that allows us to perform dependency injection in the testing
|
* An interface that allows us to perform dependency injection in the testing environment
|
||||||
* environment.
|
|
||||||
*/
|
*/
|
||||||
public interface TOCItemProvider {
|
public interface TOCItemProvider {
|
||||||
|
|
||||||
public Map<String, TOCItemExternal> getTOCItemExternalsByDisplayMapping();
|
/**
|
||||||
|
* Returns all external TOC items referenced by this provider
|
||||||
|
* @return the items
|
||||||
|
*/
|
||||||
|
public Map<String, TOCItemExternal> getExternalTocItemsById();
|
||||||
|
|
||||||
public Map<String, TOCItemDefinition> getTOCItemDefinitionsByIDMapping();
|
/**
|
||||||
|
* Returns all TOC items defined by this provider
|
||||||
|
* @return the items
|
||||||
|
*/
|
||||||
|
public Map<String, TOCItemDefinition> getTocDefinitionsByID();
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ public class LinkDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void collectTOCItemDefinitions(TOCItemProvider tocProvider) {
|
private void collectTOCItemDefinitions(TOCItemProvider tocProvider) {
|
||||||
Map<String, TOCItemDefinition> map = tocProvider.getTOCItemDefinitionsByIDMapping();
|
Map<String, TOCItemDefinition> map = tocProvider.getTocDefinitionsByID();
|
||||||
Set<Entry<String, TOCItemDefinition>> entrySet = map.entrySet();
|
Set<Entry<String, TOCItemDefinition>> entrySet = map.entrySet();
|
||||||
for (Entry<String, TOCItemDefinition> entry : entrySet) {
|
for (Entry<String, TOCItemDefinition> entry : entrySet) {
|
||||||
String key = entry.getKey();
|
String key = entry.getKey();
|
||||||
|
@ -124,7 +124,7 @@ public class LinkDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void collectTOCItemExternals(TOCItemProvider tocProvider) {
|
private void collectTOCItemExternals(TOCItemProvider tocProvider) {
|
||||||
Map<String, TOCItemExternal> map = tocProvider.getTOCItemExternalsByDisplayMapping();
|
Map<String, TOCItemExternal> map = tocProvider.getExternalTocItemsById();
|
||||||
for (TOCItemExternal tocItem : map.values()) {
|
for (TOCItemExternal tocItem : map.values()) {
|
||||||
mapOfIDsToTOCExternals.put(tocItem.getIDAttribute(), tocItem);
|
mapOfIDsToTOCExternals.put(tocItem.getIDAttribute(), tocItem);
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,8 @@ public class HelpModuleCollection implements TOCItemProvider {
|
||||||
/**
|
/**
|
||||||
* Creates a help module collection that contains only a singe help module from a help
|
* Creates a help module collection that contains only a singe help module from a help
|
||||||
* directory, not a pre-built help jar.
|
* directory, not a pre-built help jar.
|
||||||
|
* @param dir the directory containing help
|
||||||
|
* @return the help collection
|
||||||
*/
|
*/
|
||||||
public static HelpModuleCollection fromHelpDirectory(File dir) {
|
public static HelpModuleCollection fromHelpDirectory(File dir) {
|
||||||
return new HelpModuleCollection(toHelpLocations(Collections.singleton(dir)));
|
return new HelpModuleCollection(toHelpLocations(Collections.singleton(dir)));
|
||||||
|
@ -70,6 +72,8 @@ public class HelpModuleCollection implements TOCItemProvider {
|
||||||
/**
|
/**
|
||||||
* Creates a help module collection that assumes zero or more pre-built help jar files and
|
* Creates a help module collection that assumes zero or more pre-built help jar files and
|
||||||
* one help directory that is an input into the help building process.
|
* one help directory that is an input into the help building process.
|
||||||
|
* @param files the files from which to get help
|
||||||
|
* @return the help collection
|
||||||
*/
|
*/
|
||||||
public static HelpModuleCollection fromFiles(Collection<File> files) {
|
public static HelpModuleCollection fromFiles(Collection<File> files) {
|
||||||
return new HelpModuleCollection(toHelpLocations(files));
|
return new HelpModuleCollection(toHelpLocations(files));
|
||||||
|
@ -78,6 +82,8 @@ public class HelpModuleCollection implements TOCItemProvider {
|
||||||
/**
|
/**
|
||||||
* Creates a help module collection that assumes zero or more pre-built help jar files and
|
* Creates a help module collection that assumes zero or more pre-built help jar files and
|
||||||
* one help directory that is an input into the help building process.
|
* one help directory that is an input into the help building process.
|
||||||
|
* @param locations the locations from which to get help
|
||||||
|
* @return the help collection
|
||||||
*/
|
*/
|
||||||
public static HelpModuleCollection fromHelpLocations(Collection<HelpModuleLocation> locations) {
|
public static HelpModuleCollection fromHelpLocations(Collection<HelpModuleLocation> locations) {
|
||||||
return new HelpModuleCollection(locations);
|
return new HelpModuleCollection(locations);
|
||||||
|
@ -240,7 +246,7 @@ public class HelpModuleCollection implements TOCItemProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, TOCItemDefinition> getTOCItemDefinitionsByIDMapping() {
|
public Map<String, TOCItemDefinition> getTocDefinitionsByID() {
|
||||||
Map<String, TOCItemDefinition> map = new HashMap<>();
|
Map<String, TOCItemDefinition> map = new HashMap<>();
|
||||||
GhidraTOCFile TOC = inputHelp.getSourceTOCFile();
|
GhidraTOCFile TOC = inputHelp.getSourceTOCFile();
|
||||||
map.putAll(TOC.getTOCDefinitionByIDMapping());
|
map.putAll(TOC.getTOCDefinitionByIDMapping());
|
||||||
|
@ -248,7 +254,7 @@ public class HelpModuleCollection implements TOCItemProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, TOCItemExternal> getTOCItemExternalsByDisplayMapping() {
|
public Map<String, TOCItemExternal> getExternalTocItemsById() {
|
||||||
Map<String, TOCItemExternal> map = new HashMap<>();
|
Map<String, TOCItemExternal> map = new HashMap<>();
|
||||||
|
|
||||||
if (externalHelpSets.isEmpty()) {
|
if (externalHelpSets.isEmpty()) {
|
||||||
|
@ -282,18 +288,17 @@ public class HelpModuleCollection implements TOCItemProvider {
|
||||||
if (parent != null) {
|
if (parent != null) {
|
||||||
CustomTreeItemDecorator dec = (CustomTreeItemDecorator) parent.getUserObject();
|
CustomTreeItemDecorator dec = (CustomTreeItemDecorator) parent.getUserObject();
|
||||||
if (dec != null) {
|
if (dec != null) {
|
||||||
parentItem = mapByDisplay.get(dec.getDisplayText());
|
parentItem = mapByDisplay.get(dec.getTocID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ID targetID = item.getID();
|
ID targetID = item.getID();
|
||||||
|
|
||||||
String displayText = item.getDisplayText();
|
String displayText = item.getDisplayText();
|
||||||
String tocID = item.getTocID();
|
String tocId = item.getTocID();
|
||||||
String target = targetID == null ? null : targetID.getIDString();
|
String target = targetID == null ? null : targetID.getIDString();
|
||||||
TOCItemExternal external = new TOCItemExternal(parentItem, tocPath, tocID, displayText,
|
TOCItemExternal external = new TOCItemExternal(parentItem, tocPath, tocId, displayText,
|
||||||
target, item.getName(), -1);
|
target, item.getName(), -1);
|
||||||
mapByDisplay.put(displayText, external);
|
mapByDisplay.put(tocId, external);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
|
@ -304,7 +309,10 @@ public class HelpModuleCollection implements TOCItemProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Input TOC items are those that we are building for the input help module of this collection */
|
/**
|
||||||
|
* Input TOC items are those that we are building for the input help module of this collection
|
||||||
|
* @return the items
|
||||||
|
*/
|
||||||
public Collection<TOCItem> getInputTOCItems() {
|
public Collection<TOCItem> getInputTOCItems() {
|
||||||
Collection<TOCItem> items = new ArrayList<>();
|
Collection<TOCItem> items = new ArrayList<>();
|
||||||
GhidraTOCFile TOC = inputHelp.getSourceTOCFile();
|
GhidraTOCFile TOC = inputHelp.getSourceTOCFile();
|
||||||
|
|
|
@ -432,12 +432,12 @@ public class OverlayHelpTreeTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, TOCItemExternal> getTOCItemExternalsByDisplayMapping() {
|
public Map<String, TOCItemExternal> getExternalTocItemsById() {
|
||||||
return externals;
|
return externals;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, TOCItemDefinition> getTOCItemDefinitionsByIDMapping() {
|
public Map<String, TOCItemDefinition> getTocDefinitionsByID() {
|
||||||
return definitions;
|
return definitions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue