001/** 002 * GRANITE DATA SERVICES 003 * Copyright (C) 2006-2013 GRANITE DATA SERVICES S.A.S. 004 * 005 * This file is part of the Granite Data Services Platform. 006 * 007 * Granite Data Services is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * Granite Data Services is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 015 * General Public License for more details. 016 * 017 * You should have received a copy of the GNU Lesser General Public 018 * License along with this library; if not, write to the Free Software 019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 020 * USA, or see <http://www.gnu.org/licenses/>. 021 */ 022package org.granite.tide.data; 023 024import java.util.Map; 025import java.util.Map.Entry; 026 027import org.granite.clustering.DistributedData; 028import org.granite.clustering.DistributedDataFactory; 029import org.granite.context.GraniteContext; 030import org.granite.gravity.Channel; 031import org.granite.gravity.Gravity; 032import org.granite.gravity.GravityManager; 033import org.granite.logging.Logger; 034import org.granite.messaging.webapp.ServletGraniteContext; 035 036import flex.messaging.messages.AsyncMessage; 037import flex.messaging.messages.CommandMessage; 038import flex.messaging.messages.ErrorMessage; 039import flex.messaging.messages.Message; 040 041 042/** 043 * Default implementation for data update dispatchers using the Gravity API to dispatch updates. 044 * 045 * @see DataDispatcher 046 * @see DataContext 047 * 048 * @author William Drai 049 */ 050public class DefaultDataDispatcher extends AbstractDataDispatcher { 051 052 private static final Logger log = Logger.getLogger(DefaultDataDispatcher.class); 053 054 055 private Gravity gravity = null; 056 057 058 public DefaultDataDispatcher(Gravity gravity, String topicName, Class<? extends DataTopicParams> dataTopicParamsClass) { 059 super(topicName, dataTopicParamsClass); 060 061 GraniteContext graniteContext = GraniteContext.getCurrentInstance(); 062 if (gravity == null && (graniteContext == null || !(graniteContext instanceof ServletGraniteContext))) 063 return; 064 065 DistributedDataFactory distributedDataFactory = gravity != null 066 ? gravity.getGraniteConfig().getDistributedDataFactory() 067 : graniteContext.getGraniteConfig().getDistributedDataFactory(); 068 DistributedData gdd = distributedDataFactory.getInstance(); 069 if (gdd != null) { 070 this.gravity = GravityManager.getGravity(((ServletGraniteContext)graniteContext).getServletContext()); 071 072 if (this.gravity == null) { 073 log.debug("Gravity not found or HTTP session not found, data dispatch disabled"); 074 return; 075 } 076 077 clientId = gdd.getDestinationClientId(topicName); 078 subscriptionId = gdd.getDestinationSubscriptionId(topicName); 079 sessionId = graniteContext.getSessionId(); 080 } 081 else { 082 if (gravity == null) { 083 log.debug("Gravity not defined, data dispatch disabled"); 084 return; 085 } 086 087 this.gravity = gravity; 088 this.sessionId = DataDispatcher.SERVER_DISPATCHER_GDS_SESSION_ID; 089 } 090 091 enabled = true; 092 } 093 094 095 @Override 096 protected void changeDataSelector(String dataSelector) { 097 DistributedDataFactory distributedDataFactory = GraniteContext.getCurrentInstance().getGraniteConfig().getDistributedDataFactory(); 098 DistributedData gdd = distributedDataFactory.getInstance(); 099 if (gdd != null) { 100 String clientId = gdd.getDestinationClientId(topicName); 101 String subscriptionId = gdd.getDestinationSubscriptionId(topicName); 102 103 if (clientId != null) { 104 CommandMessage message = new CommandMessage(); 105 message.setClientId(clientId); 106 message.setHeader(AsyncMessage.DESTINATION_CLIENT_ID_HEADER, subscriptionId); 107 message.setHeader(AsyncMessage.SUBTOPIC_HEADER, TIDE_DATA_SUBTOPIC); 108 message.setDestination(topicName); 109 message.setOperation(CommandMessage.SUBSCRIBE_OPERATION); 110 111 message.setHeader(CommandMessage.SELECTOR_HEADER, dataSelector); 112 113 gravity.handleMessage(null, message, true); 114 115 log.debug("Topic %s data selector changed: %s", topicName, dataSelector); 116 } 117 } 118 } 119 120 @Override 121 public void publishUpdate(Map<String, String> params, Object body) { 122 AsyncMessage message = new AsyncMessage(); 123 message.setDestination(topicName); 124 for (Entry<String, String> hh : params.entrySet()) 125 message.setHeader(hh.getKey(), hh.getValue()); 126 message.setBody(body); 127 128 Message resultMessage = null; 129 if (clientId != null) { 130 Channel channel = gravity.getChannel(null, clientId); 131 message.setClientId(clientId); 132 resultMessage = gravity.publishMessage(channel, message); 133 } 134 else 135 resultMessage = gravity.publishMessage(message); 136 137 if (resultMessage instanceof ErrorMessage) 138 log.error("Could not dispatch data update on topic %s, message %s", topicName, resultMessage.toString()); 139 else 140 log.debug("Data message dispatched on topic %s", topicName); 141 } 142}