Skip to content

Commit

Permalink
Move plugin enabling to common load call, so plugins will always be c…
Browse files Browse the repository at this point in the history
…hecked for loading
  • Loading branch information
Col-E committed Feb 26, 2024
1 parent fee3dd3 commit 0429889
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -151,17 +151,27 @@ public boolean isPluginLoaded(@Nonnull String name) {
@Override
public <T extends Plugin> PluginContainer<T> loadPlugin(@Nonnull PluginContainer<T> container) throws PluginLoadException {
String name = container.getInformation().getName();

// Throw if a plugin with the same name is already loaded.
PluginLoader loader = container.getLoader();
if (nameMap.putIfAbsent(name.toLowerCase(Locale.ROOT), container) != null) {
// Plugin already exists, we do not allow multiple plugins with the same name.
// The passed in plugin container will be disabled since it shouldn't be used.
try {
logger.warn("Attempted to load duplicate instance of plugin '{}'", name);
container.getLoader().disablePlugin(container);
loader.disablePlugin(container);
} catch (Exception ignored) {
}
throw new PluginLoadException("Duplicate plugin: " + name);
}

// Update the instance registry.
instanceMap.put(container.getPlugin(), container);

// If configured, we'll want to load the plugin immediately.
if (shouldEnablePluginOnLoad(container))
loader.enablePlugin(container);

return container;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,20 +121,18 @@ default <T> Collection<T> getPluginsOfType(@Nonnull Class<T> type) {
*/
@Nonnull
default <T extends Plugin> PluginContainer<T> loadPlugin(@Nonnull ByteSource source) throws PluginLoadException {
ClassAllocator allocator = getAllocator();
for (PluginLoader loader : getLoaders()) {
try {
// Skip unsupported sources
if (!loader.isSupported(source))
continue;

// Load and record plugin container
PluginContainer<T> container = loader.load(getAllocator(), source);
PluginContainer<Plugin> existingPlugin = getPlugin(container.getInformation().getName());
// Load the plugin container from the source with the current allocator.
PluginContainer<T> container = loader.load(allocator, source);

PluginContainer<T> loadedContainer = loadPlugin(container);
if (shouldEnablePluginOnLoad(loadedContainer))
loader.enablePlugin(loadedContainer);
return loadedContainer;
// Register the plugin with the manager.
return loadPlugin(container);
} catch (IOException | UnsupportedSourceException ex) {
throw new PluginLoadException("Could not load plugin due to an error", ex);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import software.coley.recaf.plugin.*;
import software.coley.recaf.test.TestBase;
import software.coley.recaf.util.ZipCreationUtils;
import software.coley.recaf.util.io.ByteSource;
import software.coley.recaf.util.io.ByteSources;

import java.io.IOException;
Expand Down Expand Up @@ -70,7 +71,8 @@ public String description() {

try {
// Load the plugin
PluginContainer<Plugin> container = pluginManager.loadPlugin(ByteSources.wrap(zip));
ByteSource pluginSource = ByteSources.wrap(zip);
PluginContainer<Plugin> container = pluginManager.loadPlugin(pluginSource);

// Assert the information stuck
PluginInfo information = container.getInformation();
Expand All @@ -83,6 +85,13 @@ public String description() {
assertEquals(1, pluginManager.getPlugins().size());
assertSame(container, pluginManager.getPlugin(name));

// Assert that loading the same plugin twice throws an exception, and does
// not actually register a 2nd instance of the plugin.
assertThrows(PluginLoadException.class, () -> pluginManager.loadPlugin(pluginSource),
"Duplicate plugin loading should fail");
assertEquals(1, pluginManager.getPlugins().size());
assertSame(container, pluginManager.getPlugin(name));

// Now unload it
pluginManager.unloadPlugin(container);

Expand Down

0 comments on commit 0429889

Please sign in to comment.