package de.dtele.providers {
import de.dtele.providers.events.ProviderEvent;
import flash.errors.IllegalOperationError;
import flash.events.EventDispatcher;
import flash.utils.getQualifiedClassName;
/**
* Dispatched when a provider has been added
*
* @eventType de.dtele.provider.events.ProviderEvent.ADDED
*/
[Event("providerAdded", type="de.dtele.provider.events.ProviderEvent")]
/**
* Dispatched when a provider has been removed
*
* @eventType de.dtele.provider.events.ProviderEvent.REMOVED
*/
[Event("providerRemoved", type="de.dtele.provider.events.ProviderEvent")]
/**
* Manages providers for various services
*
* @author Mathias Brodala
*/
public final class ProviderManager extends EventDispatcher {
/**
* The singleton instance of the provider manager
*/
private static var _instance:ProviderManager;
public static function get instance():ProviderManager {
if (_instance == null) {
_instance = new ProviderManager();
}
return _instance;
}
/**
* List of providers
*/
private var providers:Object = {};
public function ProviderManager() {
if (_instance != null) {
throw new IllegalOperationError("Cannot instantiate " + getQualifiedClassName(this) + ". " +
"Use the singleton instance instead.");
}
}
/**
* Retrieves all providers for a service
*
* @param serviceName The name of a service
* @return A map of provider names and their providers
*/
public function getProviders(serviceName:String):Object {
var serviceProviders:Object = {};
if (serviceName in this.providers) {
var providers:Object = this.providers[serviceName];
for (var providerName:String in providers) {
serviceProviders[providerName] = providers[providerName][0];
}
}
return serviceProviders;
}
/**
* Retrieves a single provider for a service
*
* @param serviceName The name of a service
* @param providerName The name of a provider for the service
* @return The provider or null
*/
public function getProvider(serviceName:String, providerName:String):Object {
try {
return this.providers[serviceName][providerName][0];
} catch (e:Error) {}
return null;
}
/**
* Adds a new provider for a service
*
* Existing providers with the same name for the same service will be
* overriden and can be restored by removing the most recently added provider
*
* @param serviceName The name of a service
* @param providerName The name of the provider
* @param provider The provider to add
*/
public function addProvider(serviceName:String, providerName:String, provider:Object):void {
if (!(serviceName in this.providers)) {
this.providers[serviceName] = {};
}
if (!(providerName in this.providers[serviceName])) {
this.providers[serviceName][providerName] = [];
}
providers[serviceName][providerName].unshift(provider);
instance.dispatchEvent(new ProviderEvent(ProviderEvent.ADDED, provider));
}
/**
* Removes a provider from a service
*
* @param serviceName The name of a service
* @param providerName The name of the provider
* @param provider The provider to remove
*/
public function removeProvider(serviceName:String, providerName:String, provider:Object):void {
if (!(serviceName in this.providers) ||
!(providerName in this.providers[serviceName])) {
return;
}
var i:int = this.providers[serviceName][providerName].indexOf(provider);
if (i > -1) {
this.providers[serviceName][providerName].splice(i, 1);
instance.dispatchEvent(new ProviderEvent(ProviderEvent.REMOVED, provider));
if (this.providers[serviceName][providerName].length == 0) {
delete this.providers[serviceName][providerName];
}
for (var providerName:String in this.providers[serviceName]) {
return;
}
delete this.providers[serviceName];
}
}
}
}