package com.netifera.platform.internal.model.sync; import java.util.HashMap; import java.util.Map; import com.netifera.platform.api.dispatcher.DispatchException; import com.netifera.platform.api.dispatcher.DispatchMismatchException; import com.netifera.platform.api.dispatcher.IMessageDispatcher; import com.netifera.platform.api.dispatcher.IMessageDispatcherService; import com.netifera.platform.api.dispatcher.IMessageHandler; import com.netifera.platform.api.dispatcher.IMessenger; import com.netifera.platform.api.dispatcher.IProbeMessage; import com.netifera.platform.api.dispatcher.MessengerException; import com.netifera.platform.api.log.ILogManager; import com.netifera.platform.api.log.ILogger; import com.netifera.platform.api.model.IModelService; import com.netifera.platform.internal.model.Workspace; import com.netifera.platform.model.RequestModelUpdate; import com.netifera.platform.model.SetModelIdPrefix; public class ModelSynchronizer { private ILogger logger; private IModelService model; private IMessageDispatcher dispatcher; private Map<IMessenger, ChannelSynchronizer> channelSynchronizers = new HashMap<IMessenger, ChannelSynchronizer>(); private void requestUpdateHandler(IMessenger messenger, RequestModelUpdate msg) { logger.debug("Model updates requested, start updates at index " + msg.getStartingIndex()); if(channelSynchronizers.containsKey(messenger)) { respondError(messenger, msg, "Updates already being sent on this channel"); return; } final ChannelSynchronizer cs = new ChannelSynchronizer(this, messenger, logger, msg.getStartingIndex()); channelSynchronizers.put(messenger, cs); respondOk(messenger, msg); cs.start(); } private void setModelIdPrefixHandler(IMessenger messenger, SetModelIdPrefix msg) { logger.debug("Set model prefix " + msg.getPrefix()); if(model.getCurrentWorkspace().setModelIdPrefix(msg.getPrefix(), false)) { respondOk(messenger, msg); } else { respondError(messenger, msg, "Failed to set prefix id to " + msg.getPrefix()); } } private void respondOk(IMessenger messenger, IProbeMessage msg) { try { messenger.respondOk(msg); } catch (MessengerException e) { // channel closed, just return } } private void respondError(IMessenger messenger, IProbeMessage msg, String error) { try { messenger.respondError(msg, error); } catch (MessengerException e) { // channel closed, just return } } private void registerHandlers(IMessageDispatcher dispatcher) { final IMessageHandler handler = new IMessageHandler() { public void call(IMessenger messenger, IProbeMessage message) throws DispatchException { if(message instanceof RequestModelUpdate) { requestUpdateHandler(messenger, (RequestModelUpdate)message); } else if(message instanceof SetModelIdPrefix) { setModelIdPrefixHandler(messenger, (SetModelIdPrefix) message); } else { throw new DispatchMismatchException(message); } } }; dispatcher.registerMessageHandler(RequestModelUpdate.ID, handler); dispatcher.registerMessageHandler(SetModelIdPrefix.ID, handler); } synchronized void removeChannelSynchronizer(IMessenger messenger) { channelSynchronizers.remove(messenger); } Workspace getWorkspace() { return (Workspace)model.getCurrentWorkspace(); } /* OSGi DS bind methods */ protected void setDispatcher(IMessageDispatcherService dispatcherService) { dispatcher = dispatcherService.getServerDispatcher(); registerHandlers(dispatcher); } protected void unsetDispatcher(IMessageDispatcherService dispatcherService) { } protected void setLogManager(ILogManager logManager) { logger = logManager.getLogger("Model Synchronizer"); } protected void unsetLogManager(ILogManager logManager) { } protected void setModelService(IModelService modelService) { this.model = modelService; } protected void unsetModelService(IModelService modelService) { } }