package com.netifera.platform.internal.dispatcher.channels; import java.io.IOException; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.osgi.service.component.ComponentContext; import com.netifera.platform.api.channels.IChannelConnecter; import com.netifera.platform.api.channels.IChannelFactory; import com.netifera.platform.api.channels.IChannelRegistry; import com.netifera.platform.api.channels.IChannelServer; import com.netifera.platform.api.dispatcher.IMessageDispatcherService; import com.netifera.platform.api.log.ILogManager; import com.netifera.platform.api.log.ILogger; import com.netifera.platform.internal.dispatcher.DispatcherActivator; public class ChannelRegistry implements IChannelRegistry { private final static String CHANNEL_PROPERTY_PREFIX = "com.netifera.channel."; private final Map<String, IChannelFactory> channelFactories = new HashMap<String, IChannelFactory>(); /* only the ones that have been created by the registry itself with properties */ private final Set<IChannelServer> activeServers = new HashSet<IChannelServer>(); private IMessageDispatcherService dispatcherService; private ILogger logger; private volatile boolean isActivated; public boolean isChannelRegistered(String channelType) { return channelFactories.containsKey(channelType); } public IChannelConnecter createConnecter(String config) { final String channelType = configToChannelType(config); if(channelType == null) { logger.error("Illegal channel configuration description: " + config); return null; } if(channelType.equals("local")) { return new LocalChannelConnecter(dispatcherService.getClientDispatcher()); } return getFactory(channelType).createConnecter(dispatcherService.getClientDispatcher(), config); } private String configToChannelType(String channelConfig) { final String parts[] = channelConfig.split(":"); if(parts.length < 1) { return null; } else { return parts[0]; } } public IChannelServer createServer(String config) { final String channelType = configToChannelType(config); return getFactory(channelType).createServer(dispatcherService.getServerDispatcher(), config); } private IChannelFactory getFactory(String channelType) { if(!channelFactories.containsKey(channelType)) { throw new IllegalArgumentException("Request for unregistered channel type: " + channelType); } return channelFactories.get(channelType); } protected void activate(ComponentContext ctx) { logger.enableDebug(); logger.debug("Activating"); synchronized (channelFactories) { isActivated = true; startChannelsFromProperties(); } } protected void deactivate(ComponentContext ctx) { // XXX stop channels here? } private void startChannelsFromProperties() { for(String type : channelFactories.keySet()) { createChannelFromProperty(type, getProperty(type)); } } private String getProperty(String key) { return DispatcherActivator.getInstance().getProperty(CHANNEL_PROPERTY_PREFIX + key); } private void createChannelFromProperty(String type, String configData) { if(configData == null) return; logger.debug("Creating channel with data " + configData); final IChannelFactory factory = channelFactories.get(type); assert(factory != null); final IChannelServer server = factory.createServer(dispatcherService.getServerDispatcher(), configData); if(server == null) { logger.warning("Failed to create channel server of type '" + type + "' from configuration string: " + configData); return; } if(!startChannelServer(server)) { logger.warning("Failed to start channel server of type '" + type + "' created from configuration string: " + configData); return; } logger.info("Channel server of type '" + type + "' started"); activeServers.add(server); } private boolean startChannelServer(IChannelServer server) { try { server.startListening(); return true; } catch(IOException e) { logger.error("IO error attempting to start server channel", e); return false; } } protected void registerChannelFactory(IChannelFactory factory) { synchronized (channelFactories) { channelFactories.put(factory.getType(), factory); if(isActivated) createChannelFromProperty(factory.getType(), getProperty(factory.getType())); } } protected void unregisterChannelFactory(IChannelFactory factory) { synchronized (channelFactories) { channelFactories.remove(factory.getType()); } } protected void setDispatcher(IMessageDispatcherService dispatcherService) { this.dispatcherService = dispatcherService; } protected void unsetDispatcher(IMessageDispatcherService dispatcherService) { this.dispatcherService = null; } protected void setLogManager(ILogManager logManager) { logger = logManager.getLogger("Channel Registry"); } protected void unsetLogManager(ILogManager logManager) { logger = null; } }