PluginLoader { public boolean load(Plugin plugin) { if (loadedPlugins.contains(plugin)) { return false; } final Stopwatch timer = Stopwatch.createStarted(); unloadOldVersion(plugin); knownPluginClasses.add(plugin.getClass()); if (!canLoad(plugin)) { log.warning("Not all requirements are present for " + plugin.fullIdString()); if (!knownPlugins.contains(plugin)) { knownPlugins.add(plugin); } return false; } log.info("Loading plugin " + plugin.fullIdString()); dataTypes.registerAll(plugin.getDataTypes()); sourceTypes.registerAll(plugin.getSourceTypes()); plugin.getTypeAdapters().forEach(Serializers::add); components.registerAll(plugin.getComponents()); plugin.getDefaultComponents().forEach(components::setDefaultComponent); components.getActiveWidgets().stream() .filter(w -> w.getSources().stream().anyMatch(s -> s instanceof DestroyedSource)) .filter(w -> { return plugin.getComponents().stream().anyMatch(t -> t.getType().equals(w.getClass())) || w.getSources().stream().anyMatch(s -> plugin.getDataTypes().contains(s.getDataType())) || w.getSources().stream().anyMatch(s -> plugin.getSourceTypes().contains(s.getType())); }) .filter(w -> w.getSources().stream().anyMatch(s -> sourceTypes.isRegistered(s.getType()))) .forEach(w -> { w.getSources().stream() .filter(s -> s instanceof DestroyedSource) .forEach(s -> tryRestoreSource(w, (DestroyedSource) s)); }); plugin.getThemes().forEach(themes::register); tabInfoRegistry.registerAll(plugin.getDefaultTabInfo()); converters.registerAll(plugin.getRecordingConverters()); propertyParsers.registerAll(plugin.getPropertyParsers()); plugin.onLoad(); plugin.setLoaded(true); loadedPlugins.add(plugin); if (!knownPlugins.contains(plugin)) { knownPlugins.add(plugin); } log.info("Loaded plugin " + plugin.idString() + " in " + timer.elapsed(TimeUnit.MILLISECONDS) + "ms"); return true; } PluginLoader(DataTypes dataTypes,
                      SourceTypes sourceTypes,
                      Components components,
                      Themes themes,
                      TabInfoRegistry tabInfoRegistry,
                      Converters converters,
                      PropertyParsers propertyParsers); static PluginLoader getDefault(); void loadAllJarsFromDir(Path directory); void loadPluginJar(URI jarUri); boolean loadPluginClass(Class<? extends Plugin> clazz); boolean load(Plugin plugin); boolean canLoad(Plugin plugin); @SuppressWarnings("unchecked") boolean unload(Plugin plugin); ObservableList<Plugin> getKnownPlugins(); ObservableSet<Plugin> getLoadedPlugins(); ObservableList<ClassLoader> getClassLoaders();  }
@Test public void testDependentOnHigherVersion() { assumeTrue(loader.load(new MockPlugin())); assertFalse(loader.load(new DependentOnHigherVersion())); }
@Test public void testLoad() { MockPlugin plugin = new MockPlugin(); assertTrue(loader.load(plugin), "Plugin was not loaded"); assertTrue(plugin.isLoaded()); assertTrue(loader.getLoadedPlugins().contains(plugin)); assertTrue(loader.getKnownPlugins().contains(plugin)); assertTrue(dataTypes.isRegistered(MockPlugin.dataType)); assertTrue(sourceTypes.isRegistered(MockPlugin.sourceType)); assertTrue(components.isRegistered(MockPlugin.component)); assertTrue(themes.isRegistered(MockPlugin.theme)); }
@Test public void testDefaultTabs() { Plugin plugin = new DefaultTabsPlugin(); loader.load(plugin); assertTrue(tabInfoRegistry.isRegistered(DefaultTabsPlugin.tabInfo), "Tab info was not registered"); }
@Test public void testLoadDependentAlone() { boolean loaded = loader.load(new DependentPlugin()); assertFalse(loaded, "The plugin should not have been loaded without having its dependents loaded"); }
@Test public void testLoadDependent() { assumeTrue(loader.load(new MockPlugin()), "Mock plugin wasn't loaded"); assertTrue(loader.load(new DependentPlugin()), "Dependent plugin should have been loaded"); }