GT-2869 - Shared Key Bindings - created new shared keybinding concept

that replaces the DummyKeyBindingsOptionsAction
This commit is contained in:
dragonmacher 2019-05-20 12:48:56 -04:00
parent c9bd3a8b2b
commit 3705ac3d1f
8 changed files with 200 additions and 135 deletions

View file

@ -17,51 +17,46 @@ package ghidra.app.plugin.core.data;
import javax.swing.KeyStroke;
import docking.action.*;
import docking.tool.util.DockingToolConstants;
import docking.action.KeyBindingData;
import docking.action.MenuData;
import ghidra.app.context.ListingActionContext;
import ghidra.app.context.ListingContextAction;
import ghidra.framework.options.*;
import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.data.*;
import ghidra.util.HelpLocation;
/**
* Base class for actions to create data types
*/
class DataAction extends ListingContextAction implements OptionsChangeListener {
class DataAction extends ListingContextAction {
protected DataType dataType;
protected DataPlugin plugin;
private String actionName;
private DummyKeyBindingsOptionsAction dummyKeybindingsAction;
public DataAction(DataType dataType, DataPlugin plugin) {
this("Define " + dataType.getDisplayName(), "Data", dataType, plugin);
}
/**
* Constructor
*
* @param name action name
* @param group the action's group
* @param dataType the data type used by this action
* @param plugin the plugin that owns this action
*/
public DataAction(String name, String group, DataType dataType, DataPlugin plugin) {
super(name, plugin.getName(), false);
this.actionName = name;
this.plugin = plugin;
this.dataType = dataType;
setPopupMenuData(new MenuData(new String[] { "Data", dataType.getDisplayName() }, group));
assignHelpID(dataType);
initializeKeybinding();
initKeyStroke(getDefaultKeyStroke());
}
private void initializeKeybinding() {
PluginTool tool = plugin.getTool();
dummyKeybindingsAction =
new DummyKeyBindingsOptionsAction(actionName, getDefaultKeyStroke());
tool.addAction(dummyKeybindingsAction);
ToolOptions options = tool.getOptions(DockingToolConstants.KEY_BINDINGS);
options.addOptionsChangeListener(this);
KeyStroke keyStroke =
options.getKeyStroke(dummyKeybindingsAction.getFullName(), getDefaultKeyStroke());
initKeyStroke(keyStroke);
@Override
public boolean usesSharedKeyBinding() {
return true;
}
protected KeyStroke getDefaultKeyStroke() {
@ -77,8 +72,8 @@ class DataAction extends ListingContextAction implements OptionsChangeListener {
setUnvalidatedKeyBindingData(new KeyBindingData(keyStroke));
}
protected DockingAction getDummyKeyBindingAction() {
return dummyKeybindingsAction;
DataType getDataType() {
return dataType;
}
@Override
@ -99,19 +94,6 @@ class DataAction extends ListingContextAction implements OptionsChangeListener {
return plugin.isCreateDataAllowed(context);
}
@Override
public void optionsChanged(ToolOptions options, String optionName, Object oldValue,
Object newValue) {
KeyStroke keyStroke = (KeyStroke) newValue;
if (optionName.startsWith(actionName)) {
setUnvalidatedKeyBindingData(new KeyBindingData(keyStroke));
}
}
DataType getDataType() {
return dataType;
}
// Set the help ID according to the data type
private void assignHelpID(DataType dt) {
String helpID = "Favorites";

View file

@ -17,12 +17,10 @@ package ghidra.app.plugin.core.function;
import javax.swing.KeyStroke;
import docking.action.*;
import docking.tool.util.DockingToolConstants;
import docking.action.KeyBindingData;
import docking.action.MenuData;
import ghidra.app.context.ListingActionContext;
import ghidra.app.context.ListingContextAction;
import ghidra.framework.options.*;
import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.data.DataType;
import ghidra.program.util.ProgramLocation;
import ghidra.program.util.VariableLocation;
@ -31,13 +29,11 @@ import ghidra.util.HelpLocation;
/**
* Base class for actions to create data types
*/
class DataAction extends ListingContextAction implements OptionsChangeListener {
class DataAction extends ListingContextAction {
private final String group;
protected DataType dataType;
protected FunctionPlugin plugin;
private String actionName;
private DummyKeyBindingsOptionsAction dummyKeybindingsAction;
public DataAction(DataType dataType, FunctionPlugin plugin) {
this("Define " + dataType.getDisplayName(), "Function", dataType, plugin);
@ -46,26 +42,19 @@ class DataAction extends ListingContextAction implements OptionsChangeListener {
public DataAction(String name, String group, DataType dataType, FunctionPlugin plugin) {
super(name, plugin.getName(), false);
this.actionName = name;
this.group = group;
this.plugin = plugin;
this.dataType = dataType;
setPopupMenu(plugin.getDataActionMenuName(null), true);
setHelpLocation(new HelpLocation(plugin.getName(), "DataType"));
initializeKeybinding();
initKeyStroke(getDefaultKeyStroke());
}
private void initializeKeybinding() {
PluginTool tool = plugin.getTool();
dummyKeybindingsAction =
new DummyKeyBindingsOptionsAction(actionName, getDefaultKeyStroke());
tool.addAction(dummyKeybindingsAction);
ToolOptions options = tool.getOptions(DockingToolConstants.KEY_BINDINGS);
options.addOptionsChangeListener(this);
KeyStroke keyStroke =
options.getKeyStroke(dummyKeybindingsAction.getFullName(), getDefaultKeyStroke());
initKeyStroke(keyStroke);
@Override
public boolean usesSharedKeyBinding() {
return true;
}
protected KeyStroke getDefaultKeyStroke() {
@ -81,10 +70,6 @@ class DataAction extends ListingContextAction implements OptionsChangeListener {
setUnvalidatedKeyBindingData(new KeyBindingData(keyStroke));
}
protected DockingAction getDummyKeyBindingAction() {
return dummyKeybindingsAction;
}
void setPopupMenu(String name, boolean isSignatureAction) {
setPopupMenuData(new MenuData(
new String[] { FunctionPlugin.SET_DATA_TYPE_PULLRIGHT, dataType.getDisplayName() },
@ -98,11 +83,6 @@ class DataAction extends ListingContextAction implements OptionsChangeListener {
super.dispose();
}
@Override
public void actionPerformed(ListingActionContext context) {
plugin.createData(dataType, context, true);
}
@Override
protected boolean isEnabledForContext(ListingActionContext context) {
if (context.hasSelection() || context.getAddress() == null) {
@ -121,11 +101,7 @@ class DataAction extends ListingContextAction implements OptionsChangeListener {
}
@Override
public void optionsChanged(ToolOptions options, String optionName, Object oldValue,
Object newValue) {
KeyStroke keyStroke = (KeyStroke) newValue;
if (optionName.startsWith(actionName)) {
setUnvalidatedKeyBindingData(new KeyBindingData(keyStroke));
}
public void actionPerformed(ListingActionContext context) {
plugin.createData(dataType, context, true);
}
}

View file

@ -225,6 +225,10 @@ public class TestEnv {
}
public void closeTool(PluginTool toolToClose, boolean ignoreChanges) {
if (toolToClose == tool) {
tool = null;
}
extraTools.remove(toolToClose);
AbstractGenericTest.executeOnSwingWithoutBlocking(() -> {
if (ignoreChanges) {

View file

@ -32,6 +32,7 @@ import org.junit.*;
import docking.action.DockingActionIf;
import docking.options.editor.OptionsDialog;
import docking.options.editor.OptionsPanel;
import docking.tool.util.DockingToolConstants;
import docking.util.KeyBindingUtils;
import docking.widgets.filechooser.GhidraFileChooser;
import docking.widgets.tree.GTree;
@ -49,7 +50,6 @@ import ghidra.framework.options.Options;
import ghidra.framework.options.ToolOptions;
import ghidra.framework.plugintool.PluginTool;
import ghidra.framework.plugintool.mgr.OptionsManager;
import ghidra.framework.plugintool.util.ToolConstants;
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
import ghidra.test.TestEnv;
import ghidra.util.Msg;
@ -65,7 +65,6 @@ public class KeyBindingUtilsTest extends AbstractGhidraHeadedIntegrationTest {
private static final String TEST_FILENAME =
"KeyBindingUtilsTest_Test_Filename" + KeyBindingUtils.PREFERENCES_FILE_EXTENSION;
private static final String TEST_TOOL_NAME = "KeyBindingsUtilsTest_TestTool";
private Writer debug = new NullWriter();
@ -137,7 +136,7 @@ public class KeyBindingUtilsTest extends AbstractGhidraHeadedIntegrationTest {
@Test
public void testExportImportKeyBindings() throws Exception {
debug("testExportImportKeyBindings()");
ToolOptions defaultKeyBindings = tool.getOptions(ToolConstants.KEY_BINDINGS);
ToolOptions defaultKeyBindings = tool.getOptions(DockingToolConstants.KEY_BINDINGS);
debug("a");
@ -195,7 +194,7 @@ public class KeyBindingUtilsTest extends AbstractGhidraHeadedIntegrationTest {
@Test
public void testImportExportWithGUI() throws Exception {
setUpDialog();
setKeyBindingsUpDialog();
debug("a");
@ -206,11 +205,11 @@ public class KeyBindingUtilsTest extends AbstractGhidraHeadedIntegrationTest {
// save and reload them to make sure they are the same
File saveFile = exportOptions(toolKeyBindingOptions);
ToolOptions savedOptions = importOptions(saveFile);
ToolOptions originalOptions = importOptions(saveFile);
assertOptionsMatch(
"The Options objects do not contain different data after " + "changes have been made.",
toolKeyBindingOptions, savedOptions);
toolKeyBindingOptions, originalOptions);
debug("c");
@ -222,7 +221,7 @@ public class KeyBindingUtilsTest extends AbstractGhidraHeadedIntegrationTest {
// verify the changes are different than the original values
assertOptionsDontMatch(
"The Options objects do not contain different data after " + "changes have been made.",
toolKeyBindingOptions, savedOptions);
toolKeyBindingOptions, originalOptions);
debug("e");
@ -234,13 +233,13 @@ public class KeyBindingUtilsTest extends AbstractGhidraHeadedIntegrationTest {
debug("f");
// verify the data is the same as it was before the changes
boolean same = compareOptionsWithKeyStrokeMap(savedOptions, optionsMap);
boolean same = compareOptionsWithKeyStrokeMap(originalOptions, optionsMap);
assertTrue("The Options object contains different data than was " + "imported.", same);
debug("g");
// close the tool *without* applying the changes
closeAllWindowsAndFrames();
closeAllWindows();
env.dispose();
debug("h");
@ -250,7 +249,7 @@ public class KeyBindingUtilsTest extends AbstractGhidraHeadedIntegrationTest {
// reload the tool and make sure the values are those of the changes
// *before* the last import
setUp();
setUpDialog();
setKeyBindingsUpDialog();
debug("i");
@ -258,7 +257,7 @@ public class KeyBindingUtilsTest extends AbstractGhidraHeadedIntegrationTest {
assertOptionsMatch(
"The options from the first tool instance have changed " +
"in the second tool instance even though the testing changes were not applied.",
savedOptions, newlyLoadedDefaultOptions);
originalOptions, newlyLoadedDefaultOptions);
debug("j");
@ -281,44 +280,54 @@ public class KeyBindingUtilsTest extends AbstractGhidraHeadedIntegrationTest {
debug("n");
saveTool();
closeAllWindowsAndFrames();
env.dispose();
debug("o");
saveFile.delete();
// reload the tool and make sure the values are those of the changes
// *after* the last import
// reload with our saved tool
setUp();
runSwing(() -> {
ToolServices services = tool.getProject().getToolServices();
tool = (PluginTool) services.launchTool(TEST_TOOL_NAME, null);
});
saveAndCloseTool();
reopenTool(tool);
debug("p");
setKeyBindingsUpDialog(tool);
newlyLoadedDefaultOptions = (ToolOptions) getInstanceField("options", panel);
assertOptionsDontMatch(
"The options are the same after making changes, applying, " + "closing and reloading.",
savedOptions, newlyLoadedDefaultOptions);
"The options are the same after making changes, applying, closing and reloading.",
originalOptions, newlyLoadedDefaultOptions);
debug("q");
closeAllWindows();
}
private void saveTool() {
executeOnSwingWithoutBlocking(() -> tool.saveTool());
private void reopenTool(PluginTool tool2) {
runSwing(() -> {
ToolServices services = tool.getProject().getToolServices();
tool = (PluginTool) services.launchTool(tool.getName(), null);
});
assertNotNull(tool);
}
// open the options dialog and show the key bindings editor
private void setUpDialog() throws Exception {
debug("setUpDialog()");
private void saveAndCloseTool() {
runSwing(() -> {
ToolServices services = tool.getProject().getToolServices();
services.saveTool(tool);
});
env.closeTool(tool);
}
private void setKeyBindingsUpDialog() throws Exception {
env.showTool();
setKeyBindingsUpDialog(tool);
}
private void setKeyBindingsUpDialog(PluginTool pluginTool) throws Exception {
debug("setUpDialog()");
debug("aa");
final OptionsManager optionsManager = (OptionsManager) getInstanceField("optionsMgr", tool);
final OptionsManager optionsManager =
(OptionsManager) getInstanceField("optionsMgr", pluginTool);
debug("bb");
executeOnSwingWithoutBlocking(() -> {
@ -458,7 +467,7 @@ public class KeyBindingUtilsTest extends AbstractGhidraHeadedIntegrationTest {
}
private void closeWarningDialog(boolean proceed) {
Window window = waitForWindowByTitleContaining(null, "Continue", DEFAULT_WINDOW_TIMEOUT);
Window window = waitForWindowByTitleContaining("Continue");
assertNotNull(window);
String button = proceed ? "Yes" : "No";
@ -488,7 +497,7 @@ public class KeyBindingUtilsTest extends AbstractGhidraHeadedIntegrationTest {
// locates the open file chooser and verifies its state
private File findAndTestFileChooser(File path, String filename) throws Exception {
// get the file chooser and set the file it will use
GhidraFileChooser fileChooser = waitForDialogComponent(null, GhidraFileChooser.class, 5000);
GhidraFileChooser fileChooser = waitForDialogComponent(GhidraFileChooser.class);
if (fileChooser == null) {
Msg.debug(this, "Couldn't find file chooser");
printOpenWindows();

View file

@ -93,12 +93,12 @@ public class DockingToolActionManager implements PropertyChangeListener {
private void setKeyBindingOption(DockingActionIf action) {
if (!action.isKeyBindingManaged()) {
if (action.usesSharedKeyBinding()) {
installSharedKeyBinding(action);
return;
}
if (action.usesSharedKeyBinding()) {
installSharedKeyBinding(action);
if (!action.isKeyBindingManaged()) {
return;
}
@ -159,15 +159,7 @@ public class DockingToolActionManager implements PropertyChangeListener {
action.addPropertyChangeListener(this);
addActionToMap(action);
if (action.isKeyBindingManaged()) {
KeyStroke ks = action.getKeyBinding();
keyBindingOptions.registerOption(action.getFullName(), OptionType.KEYSTROKE_TYPE, ks,
null, null);
KeyStroke newKs = keyBindingOptions.getKeyStroke(action.getFullName(), ks);
if (ks != newKs) {
action.setUnvalidatedKeyBindingData(new KeyBindingData(newKs));
}
}
setKeyBindingOption(action);
winMgr.addLocalAction(provider, action);
}
@ -198,14 +190,26 @@ public class DockingToolActionManager implements PropertyChangeListener {
/**
* Get all actions that have the action name which includes the action owner's name.
*
* @param fullActionName full name for the action, e.g., "My Action (My Plugin)"
* @param fullName full name for the action, e.g., "My Action (My Plugin)"
* @return list of actions; empty if no action exists with the given name
*/
public List<DockingActionIf> getDockingActionsByFullActionName(String fullName) {
List<DockingActionIf> list = actionMap.get(fullName);
if (list == null) {
return new ArrayList<>();
list = new ArrayList<>();
}
// note: we only use the action name for the lookup, as all shared actions are owned
// by the 'Tool'
int index = fullName.indexOf(" (Tool)");
if (index > 0) {
String actionName = fullName.substring(0, index);
SharedStubKeyBindingAction sharedAction = sharedActionMap.get(actionName);
if (sharedAction != null) {
list.add(sharedAction);
}
}
return new ArrayList<>(list);
}
@ -222,8 +226,8 @@ public class DockingToolActionManager implements PropertyChangeListener {
* @return a list of deduped actions.
*/
private List<DockingActionIf> getUniqueActionList(String owner) {
List<DockingActionIf> matchingActionList = new ArrayList<>();
List<DockingActionIf> matchingActionList = new ArrayList<>();
for (List<DockingActionIf> actionList : actionMap.values()) {
// we only want *one* instance of duplicate actions
DockingActionIf action = actionList.get(0);
@ -232,6 +236,12 @@ public class DockingToolActionManager implements PropertyChangeListener {
}
}
for (DockingActionIf action : sharedActionMap.values()) {
if (owner == null || action.getOwner().equals(owner)) {
matchingActionList.add(action);
}
}
return matchingActionList;
}
@ -289,7 +299,6 @@ public class DockingToolActionManager implements PropertyChangeListener {
actionMap.remove(name);
}
}
}
@Override

View file

@ -83,7 +83,7 @@ class SharedStubKeyBindingAction extends DockingAction implements OptionsChangeL
private KeyStroke validateActionsHaveTheSameDefaultKeyStroke(DockingActionIf newAction) {
// this value may be null
KeyBindingData defaultBinding = newAction.getDefaultKeyBindingData();
KeyBindingData defaultBinding = newAction.getKeyBindingData();
KeyStroke newDefaultKs = getKeyStroke(defaultBinding);
Set<Entry<DockingActionIf, KeyStroke>> entries = clientActions.entrySet();

View file

@ -21,6 +21,7 @@ import java.awt.event.KeyEvent;
import java.util.List;
import java.util.Set;
import javax.swing.JComponent;
import javax.swing.KeyStroke;
import org.apache.commons.collections4.IterableUtils;
@ -72,6 +73,7 @@ public class SharedKeybindingDockingActionTest extends AbstractDockingTest {
assertNoLoggedMessages();
assertKeyBinding(action1, DEFAULT_KS_1);
assertKeyBinding(action2, DEFAULT_KS_1);
assertSharedStubInTool();
}
@Test
@ -89,6 +91,7 @@ public class SharedKeybindingDockingActionTest extends AbstractDockingTest {
assertNoLoggedMessages();
assertKeyBinding(action1, newKs);
assertKeyBinding(action2, newKs);
assertSharedStubInTool();
}
@Test
@ -104,6 +107,7 @@ public class SharedKeybindingDockingActionTest extends AbstractDockingTest {
assertImproperDefaultBindingMessage();
assertKeyBinding(action1, DEFAULT_KS_1);
assertKeyBinding(action2, DEFAULT_KS_1);
assertSharedStubInTool();
}
@Test
@ -119,6 +123,7 @@ public class SharedKeybindingDockingActionTest extends AbstractDockingTest {
assertNoLoggedMessages();
assertKeyBinding(action1, null);
assertKeyBinding(action2, null);
assertSharedStubInTool();
}
@Test
@ -133,6 +138,7 @@ public class SharedKeybindingDockingActionTest extends AbstractDockingTest {
assertImproperDefaultBindingMessage();
assertKeyBinding(action1, DEFAULT_KS_1);
assertKeyBinding(action2, DEFAULT_KS_1);
assertSharedStubInTool();
}
@Test
@ -168,6 +174,7 @@ public class SharedKeybindingDockingActionTest extends AbstractDockingTest {
assertNoLoggedMessages();
assertKeyBinding(action1, DEFAULT_KS_1);
assertSharedStubInTool();
}
@Test
@ -204,14 +211,81 @@ public class SharedKeybindingDockingActionTest extends AbstractDockingTest {
assertKeyBinding(action1, newKs);
}
@Test
public void testSharedKeyBinding_SameDefaultKeyBindings_LocalAction() {
TestAction action1 = new TestAction(OWNER_1, DEFAULT_KS_1);
TestAction action2 = new TestAction(OWNER_2, DEFAULT_KS_1);
DummyComponentProvider provider = new DummyComponentProvider();
tool.addLocalAction(provider, action1);
tool.addLocalAction(provider, action2);
assertNoLoggedMessages();
assertKeyBinding(action1, DEFAULT_KS_1);
assertKeyBinding(action2, DEFAULT_KS_1);
assertSharedStubInTool();
}
@Test
public void testSharedKeyBinding_RemoveAction_LocalAction() {
TestAction action1 = new TestAction(OWNER_1, DEFAULT_KS_1);
TestAction action2 = new TestAction(OWNER_2, DEFAULT_KS_1);
DummyComponentProvider provider = new DummyComponentProvider();
tool.addLocalAction(provider, action1);
tool.addLocalAction(provider, action2);
tool.removeLocalAction(provider, action1);
assertActionNotInTool(action1);
assertActionInTool(action2);
tool.removeLocalAction(provider, action2);
assertActionNotInTool(action2);
String sharedName = action1.getFullName();
assertNoSharedKeyBindingStubInstalled(sharedName);
}
@Test
public void testSharedKeyBinding_RemoveComonentActions() {
TestAction action1 = new TestAction(OWNER_1, DEFAULT_KS_1);
TestAction action2 = new TestAction(OWNER_2, DEFAULT_KS_1);
DummyComponentProvider provider = new DummyComponentProvider();
tool.addLocalAction(provider, action1);
tool.addLocalAction(provider, action2);
assertActionInTool(action1);
assertActionInTool(action2);
tool.removeComponentProvider(provider);
assertActionNotInTool(action1);
assertActionNotInTool(action2);
String sharedName = action1.getFullName();
assertNoSharedKeyBindingStubInstalled(sharedName);
}
//==================================================================================================
// Private Methods
//==================================================================================================
private void assertSharedStubInTool() {
// the stub action's name is 'Shared Action Name (Tool)'
DockingActionIf action = getAction(tool, SHARED_OWNER, SHARED_NAME);
assertNotNull("Shared action stub is not in the tool", action);
}
private void assertOnlyOneVersionOfActionInTool(TestAction action) {
Set<DockingActionIf> actions = getActions(tool, action.getName());
assertEquals("There should be only one instance of this action in the tool: " + action, 1,
actions.size());
// this method will fail if more than one action is registered
DockingActionIf registeredAction = getAction(tool, action.getOwner(), action.getName());
assertNotNull("There should be only one instance of this action in the tool: " + action,
registeredAction);
}
private void assertActionInTool(TestAction action) {
@ -234,7 +308,6 @@ public class SharedKeybindingDockingActionTest extends AbstractDockingTest {
}
private void assertNoSharedKeyBindingStubInstalled(String sharedName) {
List<DockingActionIf> actions = tool.getDockingActionsByFullActionName(sharedName);
assertTrue("There should be no actions registered for '" + sharedName + "'",
actions.isEmpty());
@ -286,4 +359,16 @@ public class SharedKeybindingDockingActionTest extends AbstractDockingTest {
fail("Action performed should not have been called");
}
}
private class DummyComponentProvider extends ComponentProvider {
public DummyComponentProvider() {
super(tool, "Dummy", "Dummy Owner");
addToTool();
}
@Override
public JComponent getComponent() {
return null;
}
}
}

View file

@ -15,6 +15,12 @@
*/
package ghidra.framework.project.tool;
import java.io.*;
import java.util.*;
import org.jdom.Document;
import org.jdom.output.XMLOutputter;
import ghidra.framework.ToolUtils;
import ghidra.framework.data.ContentHandler;
import ghidra.framework.data.DomainObjectAdapter;
@ -26,12 +32,6 @@ import ghidra.util.Msg;
import ghidra.util.classfinder.ClassSearcher;
import ghidra.util.xml.GenericXMLOutputter;
import java.io.*;
import java.util.*;
import org.jdom.Document;
import org.jdom.output.XMLOutputter;
/**
* Implementation of service used to manipulate tools.
*/
@ -42,7 +42,7 @@ class ToolServicesImpl implements ToolServices {
private ToolChest toolChest;
private ToolManagerImpl toolManager;
private List<DefaultToolChangeListener> listeners = new ArrayList<DefaultToolChangeListener>();
private List<DefaultToolChangeListener> listeners = new ArrayList<>();
private ToolChestChangeListener toolChestChangeListener;
private Set<ContentHandler> contentHandlers;
@ -189,7 +189,7 @@ class ToolServicesImpl implements ToolServices {
@Override
public Set<ToolAssociationInfo> getContentTypeToolAssociations() {
Set<ToolAssociationInfo> set = new HashSet<ToolAssociationInfo>();
Set<ToolAssociationInfo> set = new HashSet<>();
// get all known content types
Set<ContentHandler> handlers = getContentHandlers();
@ -232,7 +232,7 @@ class ToolServicesImpl implements ToolServices {
@Override
public Set<ToolTemplate> getCompatibleTools(Class<? extends DomainObject> domainClass) {
Map<String, ToolTemplate> nameToTemplateMap = new HashMap<String, ToolTemplate>();
Map<String, ToolTemplate> nameToTemplateMap = new HashMap<>();
//
// First, get all compatible tools in the tool chest
@ -290,12 +290,12 @@ class ToolServicesImpl implements ToolServices {
}
}
return new HashSet<ToolTemplate>(nameToTemplateMap.values());
return new HashSet<>(nameToTemplateMap.values());
}
private Set<ContentHandler> getCompatibleContentHandlers(
Class<? extends DomainObject> domainClass) {
Set<ContentHandler> set = new HashSet<ContentHandler>();
Set<ContentHandler> set = new HashSet<>();
Set<ContentHandler> handlers = getContentHandlers();
for (ContentHandler contentHandler : handlers) {
Class<? extends DomainObject> handlerDomainClass =
@ -327,7 +327,7 @@ class ToolServicesImpl implements ToolServices {
return contentHandlers;
}
contentHandlers = new HashSet<ContentHandler>();
contentHandlers = new HashSet<>();
Set<ContentHandler> instances = ClassSearcher.getInstances(ContentHandler.class);
for (ContentHandler contentHandler : instances) {
// a bit of validation
@ -392,7 +392,7 @@ class ToolServicesImpl implements ToolServices {
private Tool[] getSameNamedRunningTools(Tool tool) {
String toolName = tool.getToolName();
Tool[] tools = toolManager.getRunningTools();
List<Tool> toolList = new ArrayList<Tool>(tools.length);
List<Tool> toolList = new ArrayList<>(tools.length);
for (Tool element : tools) {
if (toolName.equals(element.getToolName())) {
toolList.add(element);