/** * GRANITE DATA SERVICES * Copyright (C) 2006-2015 GRANITE DATA SERVICES S.A.S. * * This file is part of the Granite Data Services Platform. * * Granite Data Services is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * Granite Data Services is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser * General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA, or see <http://www.gnu.org/licenses/>. */ package org.granite.tide.data; import java.util.Map; import java.util.Map.Entry; import org.granite.clustering.DistributedData; import org.granite.clustering.DistributedDataFactory; import org.granite.config.GraniteConfig; import org.granite.context.GraniteContext; import org.granite.gravity.Channel; import org.granite.gravity.Gravity; import org.granite.gravity.GravityManager; import org.granite.logging.Logger; import org.granite.messaging.webapp.ServletGraniteContext; import flex.messaging.messages.AsyncMessage; import flex.messaging.messages.CommandMessage; import flex.messaging.messages.ErrorMessage; import flex.messaging.messages.Message; /** * Default implementation for data update dispatchers using the Gravity API to dispatch updates. * * @see DataDispatcher * @see DataContext * * @author William Drai */ public class DefaultDataDispatcher extends AbstractDataDispatcher { private static final Logger log = Logger.getLogger(DefaultDataDispatcher.class); private Gravity gravity = null; public DefaultDataDispatcher(Gravity gravity, String topicName, Class<? extends DataTopicParams> dataTopicParamsClass) { super(topicName, dataTopicParamsClass); GraniteContext graniteContext = GraniteContext.getCurrentInstance(); if (gravity == null && (graniteContext == null || !(graniteContext instanceof ServletGraniteContext))) return; DistributedData gdd = null; if (gravity != null && gravity.isStarted()) gdd = gravity.getGraniteConfig().getDistributedDataFactory().getInstance(); else if (graniteContext != null && graniteContext.getGraniteConfig() != null) gdd = ((GraniteConfig)graniteContext.getGraniteConfig()).getDistributedDataFactory().getInstance(); if (gdd != null) { this.gravity = GravityManager.getGravity(((ServletGraniteContext)graniteContext).getServletContext()); if (this.gravity == null) { log.debug("Gravity not found or HTTP session not found, data dispatch disabled"); return; } clientId = gdd.getDestinationClientId(topicName); subscriptionId = gdd.getDestinationSubscriptionId(topicName); sessionId = graniteContext.getSessionId(); } else { if (gravity == null && graniteContext instanceof ServletGraniteContext) gravity = GravityManager.getGravity(((ServletGraniteContext)graniteContext).getServletContext()); if (gravity == null) { log.debug("Gravity not defined, data dispatch disabled"); return; } this.gravity = gravity; this.sessionId = DataDispatcher.SERVER_DISPATCHER_GDS_SESSION_ID; } enabled = true; } @Override protected void changeDataSelector(String dataSelector) { DistributedDataFactory distributedDataFactory = ((GraniteConfig)GraniteContext.getCurrentInstance().getGraniteConfig()).getDistributedDataFactory(); DistributedData gdd = distributedDataFactory.getInstance(); if (gdd != null) { String clientId = gdd.getDestinationClientId(topicName); String subscriptionId = gdd.getDestinationSubscriptionId(topicName); if (clientId != null) { CommandMessage message = new CommandMessage(); message.setClientId(clientId); message.setHeader(AsyncMessage.DESTINATION_CLIENT_ID_HEADER, subscriptionId); message.setHeader(AsyncMessage.SUBTOPIC_HEADER, TIDE_DATA_SUBTOPIC); message.setDestination(topicName); message.setOperation(CommandMessage.SUBSCRIBE_OPERATION); message.setHeader(CommandMessage.SELECTOR_HEADER, dataSelector); gravity.handleMessage(message, true); log.debug("Topic %s data selector changed: %s", topicName, dataSelector); } } } @Override public void publishUpdate(Map<String, Object> params, Object body) { AsyncMessage message = new AsyncMessage(); message.setDestination(topicName); for (Entry<String, Object> hh : params.entrySet()) message.setHeader(hh.getKey(), hh.getValue()); message.setBody(body); Message resultMessage = null; if (clientId != null) { Channel channel = gravity.findChannelByClientId(clientId); message.setClientId(clientId); resultMessage = gravity.publishMessage(channel, message); } else resultMessage = gravity.publishMessage(message); if (resultMessage instanceof ErrorMessage) log.error("Could not dispatch data update on topic %s, message %s", topicName, resultMessage.toString()); else log.debug("Data message dispatched on topic %s", topicName); } }