/**
  * Finally activates a plugin. Called once the plugin's requirements are met (see
  * PluginImpl.checkRequirementsForActivation()).
  *
  * <p>Activation comprises: - install the plugin in the database (includes migrations,
  * post-install event, type introduction) - initialize the plugin - register the plugin's
  * listeners - add the plugin to the pool of activated plugins
  *
  * <p>If this plugin is already activated, nothing is performed and false is returned. Otherwise
  * true is returned.
  *
  * <p>Note: this method is synchronized. While a plugin is activated no other plugin must be
  * activated. Otherwise the "type introduction" mechanism might miss some types. Consider this
  * unsynchronized scenario: plugin B starts running its migrations just in the moment between
  * plugin A's type introduction and listener registration. Plugin A might miss some of the types
  * created by plugin B.
  */
 synchronized boolean activatePlugin(PluginImpl plugin) {
   try {
     // Note: we must not activate a plugin twice.
     // This would happen e.g. if a dependency plugin is redeployed.
     if (isPluginActivated(plugin.getUri())) {
       logger.info("Activation of " + plugin + " ABORTED -- already activated");
       return false;
     }
     //
     logger.info("----- Activating " + plugin + " -----");
     plugin.installPluginInDB();
     plugin.initializePlugin();
     plugin.registerListeners();
     // Note: registering the listeners is deferred until the plugin is installed in the database
     // and the
     // POST_INSTALL_PLUGIN event is delivered (see PluginImpl.installPluginInDB()).
     // Consider the Access Control plugin: it can't set a topic's creator before the "admin" user
     // is created.
     addToActivatedPlugins(plugin);
     logger.info("----- Activation of " + plugin + " complete -----");
     return true;
   } catch (Exception e) {
     throw new RuntimeException("Activation of " + plugin + " failed", e);
   }
 }
 void deactivatePlugin(PluginImpl plugin) {
   plugin.unregisterListeners();
   removeFromActivatedPlugins(plugin.getUri());
 }
 private void addToActivatedPlugins(PluginImpl plugin) {
   activatedPlugins.put(plugin.getUri(), plugin);
 }