package gw.api.plugin uses gw.api.locale.DisplayKey uses gw.api.startable.IStartablePlugin uses gw.api.startable.StartablePluginCallbackHandler uses gw.api.startable.StartablePluginState /** * This class may be used as the base class for Gosu distributed or singleton plugins. It provides all the common * code for starting and stopping a plugin. For distributed plugins (annotated with @Distributed), an instance of the * plugin runs in every server instance in the cluster. For singleton plugins (not annotated with @Distributed), only one * instance of the plugin runs on a server with the appropriate role in the cluster. */ @Export abstract public class GosuStartablePluginBase implements IStartablePlugin { var _pluginCallbackHandler: StartablePluginCallbackHandler var _state = StartablePluginState.Stopped private property set State(state: StartablePluginState) { StartablePluginBase.persistState(_pluginCallbackHandler, state); _state = state; } /** * Should only be called from the start(StartablePluginCallbackHandler pluginCallbackHandler, boolean serverStarting) method. * * @param pluginCallbackHandler Implementation of StartablePluginCallbackHandler that executes as the system user. * @param serverStarting true if the request comes from the fact that the server is starting, false if it comes from the UI * @param startBlock the customer initialization code that should be run at startup * @throws IllegalArgumentException if pluginCallbackHandler cannot be initialized */ protected function innerStart(pluginCallbackHandler: StartablePluginCallbackHandler, serverStarting: boolean, startBlock: block()) { if (pluginCallbackHandler == null) { if (_pluginCallbackHandler == null) { throw new IllegalArgumentException(DisplayKey.get("PluginHandler.MayNotBeNull", PluginName)) } } else { _pluginCallbackHandler = pluginCallbackHandler } var tempState = (serverStarting) ? _pluginCallbackHandler.getState(StartablePluginState.Started) : StartablePluginState.Started if (tempState == StartablePluginState.Started) { if (startBlock != null) { startBlock() } _pluginCallbackHandler.logStart(PluginName) } else { _pluginCallbackHandler.logStop(PluginName) } if (serverStarting) { _state = tempState } else { State = tempState } _pluginCallbackHandler.log(DisplayKey.get("PluginHandler.StateOfPlugin", PluginName, _state)) } /** * Called during server startup or runlevel change and from the UI. If subclasses have any initialization code that needs to be run, * they should override this method so that it: *

* 1.) includes that initialization code in a lambda expression assigned to the startBlock variable * 2.) calls innerStart. *

* The call to innerStart will execute the initialization code within the appropriate context. * * @param pluginCallbackHandler Implementation of StartablePluginCallbackHandler that executes as the system user. * @param serverStarting true if the request comes from the fact that the server is starting, false if it comes from the UI */ override public function start(pluginCallbackHandler: StartablePluginCallbackHandler, serverStarting: boolean) { var startupBlock: block() = null innerStart(pluginCallbackHandler, serverStarting, startupBlock) } /** * Should only be called from the stop(boolean serverShuttingDown) method. * * @param serverShuttingDown true if the request comes from the fact that the server is stopping, false if it comes from the UI * @param stopBlock the customer shutdown code that should be run at shutdown (should be idempotent -- able to be called multiple times) */ protected function innerStop(serverShuttingDown: boolean, stopBlock: block()) { if (_pluginCallbackHandler != null) { if (stopBlock != null) { stopBlock() } _pluginCallbackHandler.logStop(PluginName) if (serverShuttingDown) { _state = StartablePluginState.Stopped } else { State = StartablePluginState.Stopped } _pluginCallbackHandler.log(DisplayKey.get("PluginHandler.StateOfPlugin", PluginName, _state)) } } /** * Called during server shutdown or runlevel change and from the UI. If subclasses have any shutdown code that needs to be run, * they should override this method so that it: *

* 1.) includes that initialization code in a lambda expression assigned to the stopBlock variable * 2.) calls innerStop. *

* The call to innerStop will execute the initialization code within the appropriate context. * * @param serverShuttingDown true if the request comes from the fact that the server is shutting down, false if it comes from the UI */ override public function stop(serverShuttingDown: boolean) { var stopBlock: block() = null innerStop(serverShuttingDown, stopBlock) } /** * @return the State of this plugin */ override public property get State(): StartablePluginState { return _state } protected property get PluginName(): String { return this.Class.Name } protected property get CallbackHandler(): StartablePluginCallbackHandler { return _pluginCallbackHandler } protected function log(message: String) { _pluginCallbackHandler.log(message) } }