/* * (C) Copyright IBM Corp. 2010 * * LICENSE: Eclipse Public License v1.0 * http://www.eclipse.org/legal/epl-v10.html */ package com.ibm.gaiandb.udpdriver.client; import java.util.Arrays; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ConcurrentMap; import com.ibm.gaiandb.Logger; import com.ibm.gaiandb.udpdriver.common.SocketHelper; import com.ibm.gaiandb.udpdriver.common.protocol.Message; import com.ibm.gaiandb.udpdriver.common.protocol.MessageFactory; import com.ibm.gaiandb.diags.GDBMessages; /** * Listener on a SocketHelper. * The listened port is automatically provided by the system. * When receiving a new datagram, the listener behavior is : * 1 - Check if it is a STOP message, if yes it stops to listen and properly closes its SocketHelper. * 2 - Transform the datagram into a UDP driver protocol message * 3 - Place the new UDP driver protocol message in a concurrent structure so the application threads, * running Statement or PreparedStatement objects, could reach it. * * @author lengelle * */ public class ClientListener implements Runnable { // Use PROPRIETARY notice if class contains a main() method, otherwise use COPYRIGHT notice. public static final String COPYRIGHT_NOTICE = "(c) Copyright IBM Corp. 2010"; private static final Logger logger = new Logger( "ClientListener", 25 ); /** * If the ClientListener receives this message, it automatically stops its activity and closes its SocketHelper. */ public final static byte[] STOP_MESSAGE = { 'S', 'T', 'O', 'P' }; private Thread thread; private SocketHelper clientSocket; private ConcurrentMap< String, BlockingQueue<Message> > map; /** * Creates a new ClientListener. * * @param clientSocket the SocketHelper to listen on * @param map the structure shared by the application threads */ public ClientListener( SocketHelper clientSocket, ConcurrentMap< String, BlockingQueue<Message> > map ) { this.thread = new Thread( this,"UDP ClientListener" ); this.clientSocket = clientSocket; this.map = map; } /** * Starts listening */ public void start() { thread.start(); } /** * This method should not be used. * It is preferable to use start() */ public void run() { try { Message message = null; byte[] inputData = null; while ( true ) { try { clientSocket.receive(); inputData = clientSocket.getByteArrayMessage(); if ( Arrays.equals( inputData, STOP_MESSAGE ) ) { break; } message = MessageFactory.getMessage( inputData ); addToConcurrentMap( message ); } catch( Exception e ) { logger.logException( GDBMessages.NETDRIVER_CLIENT_LISTENER_ERROR, "ClientListener run() failed.", e ); } } } finally { clientSocket.close(); } } /** * Add a message to the concurrent structure * * @param message */ private void addToConcurrentMap( Message message ) { if ( map==null || message==null ) { return; } String key = message.getQueryID(); if( map.containsKey( key ) ) { map.get( key ).offer( message ); } } // private static boolean isStopMessage( byte[] message ) // { // return Arrays.equals( message, STOP_MESSAGE ); //( message.length == STOP_MESSAGE.length ); // } }