test_class.declarator: PLUGIN_PACKAGE = "net.runelite.client.plugins"
test_class.modifier: private static final
test_class.original_string: private static final String PLUGIN_PACKAGE = "net.runelite.client.plugins";
test_class.type: String
test_class.var_name: PLUGIN_PACKAGE
test_class.declarator: folder = new TemporaryFolder()
test_class.modifier: @Rule
  	public
test_class.original_string: @Rule
  	public TemporaryFolder folder = new TemporaryFolder();
test_class.type: TemporaryFolder
test_class.var_name: folder
test_class.declarator: applet
test_class.modifier: @Mock
  	@Bind
  	public
test_class.original_string: @Mock
  	@Bind
  	public Applet applet;
test_class.type: Applet
test_class.var_name: applet
test_class.declarator: client
test_class.modifier: @Mock
  	@Bind
  	public
test_class.original_string: @Mock
  	@Bind
  	public Client client;
test_class.type: Client
test_class.var_name: client
test_class.declarator: pluginClasses
test_class.modifier: private
test_class.original_string: private Set<Class<?>> pluginClasses;
test_class.type: Set<Class<?>>
test_class.var_name: pluginClasses
test_class.declarator: configClasses
test_class.modifier: private
test_class.original_string: private Set<Class<?>> configClasses;
test_class.type: Set<Class<?>>
test_class.var_name: configClasses
test_class.file: runelite-client/src/test/java/net/runelite/client/plugins/PluginManagerTest.java
test_class.identifier: PluginManagerTest
test_case.body: @Test
  	public void testLoadPlugins() throws Exception
  	{
  		PluginManager pluginManager = new PluginManager(false, false, null, null, null, null, null);
  		pluginManager.setOutdated(true);
  		pluginManager.loadCorePlugins();
  		Collection<Plugin> plugins = pluginManager.getPlugins();
  		long expected = pluginClasses.stream()
  			.map(cl -> cl.getAnnotation(PluginDescriptor.class))
  			.filter(Objects::nonNull)
  			.filter(PluginDescriptor::loadWhenOutdated)
  			.count();
  		assertEquals(expected, plugins.size());
  
  		pluginManager = new PluginManager(false, false, null, null, null, null, null);
  		pluginManager.loadCorePlugins();
  		plugins = pluginManager.getPlugins();
  
  		// Check that the plugins register with the eventbus without errors
  		EventBus eventBus = new EventBus();
  		plugins.forEach(eventBus::register);
  
  		expected = pluginClasses.stream()
  			.map(cl -> cl.getAnnotation(PluginDescriptor.class))
  			.filter(Objects::nonNull)
  			.filter(pd -> !pd.developerPlugin())
  			.count();
  		assertEquals(expected, plugins.size());
  	}
test_case.class_method_signature: PluginManagerTest.testLoadPlugins()
test_case.full_signature: @Test public void testLoadPlugins()
test_case.identifier: testLoadPlugins
test_case.invocations: setOutdated loadCorePlugins getPlugins count filter filter map stream getAnnotation assertEquals size loadCorePlugins getPlugins forEach count filter filter map stream getAnnotation developerPlugin assertEquals size
test_case.modifiers: @Test public
test_case.parameters: ()
test_case.return: void
test_case.signature: void testLoadPlugins()
focal_class.declarator: PLUGIN_PACKAGE = "net.runelite.client.plugins"
focal_class.modifier: private static final
focal_class.original_string: private static final String PLUGIN_PACKAGE = "net.runelite.client.plugins";
focal_class.type: String
focal_class.var_name: PLUGIN_PACKAGE
focal_class.declarator: developerMode
focal_class.modifier: private final
focal_class.original_string: private final boolean developerMode;
focal_class.type: boolean
focal_class.var_name: developerMode
focal_class.declarator: safeMode
focal_class.modifier: private final
focal_class.original_string: private final boolean safeMode;
focal_class.type: boolean
focal_class.var_name: safeMode
focal_class.declarator: eventBus
focal_class.modifier: private final
focal_class.original_string: private final EventBus eventBus;
focal_class.type: EventBus
focal_class.var_name: eventBus
focal_class.declarator: scheduler
focal_class.modifier: private final
focal_class.original_string: private final Scheduler scheduler;
focal_class.type: Scheduler
focal_class.var_name: scheduler
focal_class.declarator: configManager
focal_class.modifier: private final
focal_class.original_string: private final ConfigManager configManager;
focal_class.type: ConfigManager
focal_class.var_name: configManager
focal_class.declarator: executor
focal_class.modifier: private final
focal_class.original_string: private final ScheduledExecutorService executor;
focal_class.type: ScheduledExecutorService
focal_class.var_name: executor
focal_class.declarator: sceneTileManager
focal_class.modifier: private final
focal_class.original_string: private final Provider<GameEventManager> sceneTileManager;
focal_class.type: Provider<GameEventManager>
focal_class.var_name: sceneTileManager
focal_class.declarator: plugins = new CopyOnWriteArrayList<>()
focal_class.modifier: private final
focal_class.original_string: private final List<Plugin> plugins = new CopyOnWriteArrayList<>();
focal_class.type: List<Plugin>
focal_class.var_name: plugins
focal_class.declarator: activePlugins = new CopyOnWriteArrayList<>()
focal_class.modifier: private final
focal_class.original_string: private final List<Plugin> activePlugins = new CopyOnWriteArrayList<>();
focal_class.type: List<Plugin>
focal_class.var_name: activePlugins
focal_class.declarator: isOutdated
focal_class.modifier: @Setter
focal_class.original_string: @Setter
  	boolean isOutdated;
focal_class.type: boolean
focal_class.var_name: isOutdated
focal_class.file: runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java
focal_class.identifier: PluginManager
focal_class.class_method_signature: PluginManager.PluginManager(
  		@Named("developerMode") final boolean developerMode,
  		@Named("safeMode") final boolean safeMode,
  		final EventBus eventBus,
  		final Scheduler scheduler,
  		final ConfigManager configManager,
  		final ScheduledExecutorService executor,
  		final Provider<GameEventManager> sceneTileManager)
focal_class.full_signature: @Inject @VisibleForTesting  PluginManager(
  		@Named("developerMode") final boolean developerMode,
  		@Named("safeMode") final boolean safeMode,
  		final EventBus eventBus,
  		final Scheduler scheduler,
  		final ConfigManager configManager,
  		final ScheduledExecutorService executor,
  		final Provider<GameEventManager> sceneTileManager)
focal_class.identifier: PluginManager
focal_class.modifiers: @Inject @VisibleForTesting
focal_class.parameters: (
  		@Named("developerMode") final boolean developerMode,
  		@Named("safeMode") final boolean safeMode,
  		final EventBus eventBus,
  		final Scheduler scheduler,
  		final ConfigManager configManager,
  		final ScheduledExecutorService executor,
  		final Provider<GameEventManager> sceneTileManager)
focal_class.signature:  PluginManager(
  		@Named("developerMode") final boolean developerMode,
  		@Named("safeMode") final boolean safeMode,
  		final EventBus eventBus,
  		final Scheduler scheduler,
  		final ConfigManager configManager,
  		final ScheduledExecutorService executor,
  		final Provider<GameEventManager> sceneTileManager)
focal_class.class_method_signature: PluginManager.onSessionOpen(SessionOpen event)
focal_class.full_signature: @Subscribe public void onSessionOpen(SessionOpen event)
focal_class.identifier: onSessionOpen
focal_class.modifiers: @Subscribe public
focal_class.parameters: (SessionOpen event)
focal_class.return: void
focal_class.signature: void onSessionOpen(SessionOpen event)
focal_class.class_method_signature: PluginManager.onSessionClose(SessionClose event)
focal_class.full_signature: @Subscribe public void onSessionClose(SessionClose event)
focal_class.identifier: onSessionClose
focal_class.modifiers: @Subscribe public
focal_class.parameters: (SessionClose event)
focal_class.return: void
focal_class.signature: void onSessionClose(SessionClose event)
focal_class.class_method_signature: PluginManager.refreshPlugins()
focal_class.full_signature: private void refreshPlugins()
focal_class.identifier: refreshPlugins
focal_class.modifiers: private
focal_class.parameters: ()
focal_class.return: void
focal_class.signature: void refreshPlugins()
focal_class.class_method_signature: PluginManager.getPluginConfigProxy(Plugin plugin)
focal_class.full_signature: public Config getPluginConfigProxy(Plugin plugin)
focal_class.identifier: getPluginConfigProxy
focal_class.modifiers: public
focal_class.parameters: (Plugin plugin)
focal_class.return: Config
focal_class.signature: Config getPluginConfigProxy(Plugin plugin)
focal_class.class_method_signature: PluginManager.getPluginConfigProxies(Collection<Plugin> plugins)
focal_class.full_signature: public List<Config> getPluginConfigProxies(Collection<Plugin> plugins)
focal_class.identifier: getPluginConfigProxies
focal_class.modifiers: public
focal_class.parameters: (Collection<Plugin> plugins)
focal_class.return: List<Config>
focal_class.signature: List<Config> getPluginConfigProxies(Collection<Plugin> plugins)
focal_class.class_method_signature: PluginManager.loadDefaultPluginConfiguration(Collection<Plugin> plugins)
focal_class.full_signature: public void loadDefaultPluginConfiguration(Collection<Plugin> plugins)
focal_class.identifier: loadDefaultPluginConfiguration
focal_class.modifiers: public
focal_class.parameters: (Collection<Plugin> plugins)
focal_class.return: void
focal_class.signature: void loadDefaultPluginConfiguration(Collection<Plugin> plugins)
focal_class.class_method_signature: PluginManager.startPlugins()
focal_class.full_signature: public void startPlugins()
focal_class.identifier: startPlugins
focal_class.modifiers: public
focal_class.parameters: ()
focal_class.return: void
focal_class.signature: void startPlugins()
focal_class.class_method_signature: PluginManager.loadCorePlugins()
focal_class.full_signature: public void loadCorePlugins()
focal_class.identifier: loadCorePlugins
focal_class.modifiers: public
focal_class.parameters: ()
focal_class.return: void
focal_class.signature: void loadCorePlugins()
focal_class.class_method_signature: PluginManager.loadPlugins(List<Class<?>> plugins, BiConsumer<Integer, Integer> onPluginLoaded)
focal_class.full_signature: public List<Plugin> loadPlugins(List<Class<?>> plugins, BiConsumer<Integer, Integer> onPluginLoaded)
focal_class.identifier: loadPlugins
focal_class.modifiers: public
focal_class.parameters: (List<Class<?>> plugins, BiConsumer<Integer, Integer> onPluginLoaded)
focal_class.return: List<Plugin>
focal_class.signature: List<Plugin> loadPlugins(List<Class<?>> plugins, BiConsumer<Integer, Integer> onPluginLoaded)
focal_class.class_method_signature: PluginManager.startPlugin(Plugin plugin)
focal_class.full_signature: public boolean startPlugin(Plugin plugin)
focal_class.identifier: startPlugin
focal_class.modifiers: public
focal_class.parameters: (Plugin plugin)
focal_class.return: boolean
focal_class.signature: boolean startPlugin(Plugin plugin)
focal_class.class_method_signature: PluginManager.stopPlugin(Plugin plugin)
focal_class.full_signature: public boolean stopPlugin(Plugin plugin)
focal_class.identifier: stopPlugin
focal_class.modifiers: public
focal_class.parameters: (Plugin plugin)
focal_class.return: boolean
focal_class.signature: boolean stopPlugin(Plugin plugin)
focal_class.class_method_signature: PluginManager.setPluginEnabled(Plugin plugin, boolean enabled)
focal_class.full_signature: public void setPluginEnabled(Plugin plugin, boolean enabled)
focal_class.identifier: setPluginEnabled
focal_class.modifiers: public
focal_class.parameters: (Plugin plugin, boolean enabled)
focal_class.return: void
focal_class.signature: void setPluginEnabled(Plugin plugin, boolean enabled)
focal_class.class_method_signature: PluginManager.isPluginEnabled(Plugin plugin)
focal_class.full_signature: public boolean isPluginEnabled(Plugin plugin)
focal_class.identifier: isPluginEnabled
focal_class.modifiers: public
focal_class.parameters: (Plugin plugin)
focal_class.return: boolean
focal_class.signature: boolean isPluginEnabled(Plugin plugin)
focal_class.class_method_signature: PluginManager.instantiate(List<Plugin> scannedPlugins, Class<Plugin> clazz)
focal_class.full_signature: private Plugin instantiate(List<Plugin> scannedPlugins, Class<Plugin> clazz)
focal_class.identifier: instantiate
focal_class.modifiers: private
focal_class.parameters: (List<Plugin> scannedPlugins, Class<Plugin> clazz)
focal_class.return: Plugin
focal_class.signature: Plugin instantiate(List<Plugin> scannedPlugins, Class<Plugin> clazz)
focal_class.class_method_signature: PluginManager.add(Plugin plugin)
focal_class.full_signature: public void add(Plugin plugin)
focal_class.identifier: add
focal_class.modifiers: public
focal_class.parameters: (Plugin plugin)
focal_class.return: void
focal_class.signature: void add(Plugin plugin)
focal_class.class_method_signature: PluginManager.remove(Plugin plugin)
focal_class.full_signature: public void remove(Plugin plugin)
focal_class.identifier: remove
focal_class.modifiers: public
focal_class.parameters: (Plugin plugin)
focal_class.return: void
focal_class.signature: void remove(Plugin plugin)
focal_class.class_method_signature: PluginManager.getPlugins()
focal_class.full_signature: public Collection<Plugin> getPlugins()
focal_class.identifier: getPlugins
focal_class.modifiers: public
focal_class.parameters: ()
focal_class.return: Collection<Plugin>
focal_class.signature: Collection<Plugin> getPlugins()
focal_class.class_method_signature: PluginManager.schedule(Plugin plugin)
focal_class.full_signature: private void schedule(Plugin plugin)
focal_class.identifier: schedule
focal_class.modifiers: private
focal_class.parameters: (Plugin plugin)
focal_class.return: void
focal_class.signature: void schedule(Plugin plugin)
focal_class.class_method_signature: PluginManager.unschedule(Plugin plugin)
focal_class.full_signature: private void unschedule(Plugin plugin)
focal_class.identifier: unschedule
focal_class.modifiers: private
focal_class.parameters: (Plugin plugin)
focal_class.return: void
focal_class.signature: void unschedule(Plugin plugin)
focal_class.class_method_signature: PluginManager.topologicalSort(Graph<T> graph)
focal_class.full_signature: private List<T> topologicalSort(Graph<T> graph)
focal_class.identifier: topologicalSort
focal_class.modifiers: private
focal_class.parameters: (Graph<T> graph)
focal_class.return: List<T>
focal_class.signature: List<T> topologicalSort(Graph<T> graph)
focal_method.body: public List<Plugin> loadPlugins(List<Class<?>> plugins, BiConsumer<Integer, Integer> onPluginLoaded) throws PluginInstantiationException
  	{
  		MutableGraph<Class<? extends Plugin>> graph = GraphBuilder
  			.directed()
  			.build();
  
  		for (Class<?> clazz : plugins)
  		{
  			PluginDescriptor pluginDescriptor = clazz.getAnnotation(PluginDescriptor.class);
  
  			if (pluginDescriptor == null)
  			{
  				if (clazz.getSuperclass() == Plugin.class)
  				{
  					log.warn("Class {} is a plugin, but has no plugin descriptor", clazz);
  				}
  				continue;
  			}
  
  			if (clazz.getSuperclass() != Plugin.class)
  			{
  				log.warn("Class {} has plugin descriptor, but is not a plugin", clazz);
  				continue;
  			}
  
  			if (!pluginDescriptor.loadWhenOutdated() && isOutdated)
  			{
  				continue;
  			}
  
  			if (pluginDescriptor.developerPlugin() && !developerMode)
  			{
  				continue;
  			}
  
  			if (safeMode && !pluginDescriptor.loadInSafeMode())
  			{
  				log.debug("Disabling {} due to safe mode", clazz);
  				// also disable the plugin from autostarting later
  				configManager.unsetConfiguration(RuneLiteConfig.GROUP_NAME, clazz.getSimpleName().toLowerCase());
  				continue;
  			}
  
  			Class<Plugin> pluginClass = (Class<Plugin>) clazz;
  			graph.addNode(pluginClass);
  		}
  
  		// Build plugin graph
  		for (Class<? extends Plugin> pluginClazz : graph.nodes())
  		{
  			PluginDependency[] pluginDependencies = pluginClazz.getAnnotationsByType(PluginDependency.class);
  
  			for (PluginDependency pluginDependency : pluginDependencies)
  			{
  				if (graph.nodes().contains(pluginDependency.value()))
  				{
  					graph.putEdge(pluginClazz, pluginDependency.value());
  				}
  			}
  		}
  
  		if (Graphs.hasCycle(graph))
  		{
  			throw new PluginInstantiationException("Plugin dependency graph contains a cycle!");
  		}
  
  		List<Class<? extends Plugin>> sortedPlugins = topologicalSort(graph);
  		sortedPlugins = Lists.reverse(sortedPlugins);
  
  		int loaded = 0;
  		List<Plugin> newPlugins = new ArrayList<>();
  		for (Class<? extends Plugin> pluginClazz : sortedPlugins)
  		{
  			Plugin plugin;
  			try
  			{
  				plugin = instantiate(this.plugins, (Class<Plugin>) pluginClazz);
  				newPlugins.add(plugin);
  				this.plugins.add(plugin);
  			}
  			catch (PluginInstantiationException ex)
  			{
  				log.warn("Error instantiating plugin!", ex);
  			}
  
  			loaded++;
  			if (onPluginLoaded != null)
  			{
  				onPluginLoaded.accept(loaded, sortedPlugins.size());
  			}
  		}
  
  		return newPlugins;
  	}
focal_method.class_method_signature: PluginManager.loadPlugins(List<Class<?>> plugins, BiConsumer<Integer, Integer> onPluginLoaded)
focal_method.full_signature: public List<Plugin> loadPlugins(List<Class<?>> plugins, BiConsumer<Integer, Integer> onPluginLoaded)
focal_method.identifier: loadPlugins
focal_method.invocations: build directed getAnnotation getSuperclass warn getSuperclass warn loadWhenOutdated developerPlugin loadInSafeMode debug unsetConfiguration toLowerCase getSimpleName addNode nodes getAnnotationsByType contains nodes value putEdge value hasCycle topologicalSort reverse instantiate add add warn accept size
focal_method.modifiers: public
focal_method.parameters: (List<Class<?>> plugins, BiConsumer<Integer, Integer> onPluginLoaded)
focal_method.return: List<Plugin>
focal_method.signature: List<Plugin> loadPlugins(List<Class<?>> plugins, BiConsumer<Integer, Integer> onPluginLoaded)