/*
 * MessageHandlerTable.java
 *
 * Created on February 5, 2002, 2:18 PM
 */

package xal.tools.messaging;

import java.util.*;
import java.util.logging.*;


/**
 * MessageHandlerTable is a utility class that serves to conveniently store
 * and retrieve MessageHandlers.  Handlers are accessed via source and protocol.
 * @author  tap
 */
class MessageHandlerTable implements java.io.Serializable {
    /** serialization ID */
    private static final long serialVersionUID = 1L;
    
    private Map protocolTable;

    
    /** Creates new MessageHandlerTable */
    public MessageHandlerTable() {
        protocolTable = new Hashtable();
    }
    
    
    /** add the handler to the table */
    public void addHandler( final MessageHandler handler ) {
        Class protocol = handler.getProtocol();
        Object protocolKey = protocolKey( protocol );
        Object source = handler.getSource();
        Map sourceTable;
        
        if ( protocolTable.containsKey( protocolKey ) ) {
            sourceTable = (Map)protocolTable.get( protocolKey );
        }
        else {
            sourceTable = new HashMap();
            protocolTable.put( protocolKey, sourceTable );
        }
        
        if ( sourceTable.containsKey( source ) ) {
            return;
        }
        
        sourceTable.put( source, handler );
    }
    
    
    /** remove the handler from the table */ 
    public void removeHandler( final MessageHandler handler ) {
        Class protocol = handler.getProtocol();
        Object source = handler.getSource();
        Object protocolKey = protocolKey( protocol );
        
        if ( protocolTable.containsKey( protocolKey ) ) {
            Map sourceTable = (Map)protocolTable.get( protocolKey );
            sourceTable.remove( source );
        }    
    }
    
    
    /** remove from the table the handler associated with the source and protocol */
    public <T> void removeHandler( final Object source, final Class<T> protocol ) {
        MessageHandler<T> handler = getHandler( source, protocol );
        if ( handler != null ) {
            removeHandler( handler );
        }
        else {
			final String ERROR_MESSAGE = "Error!  Attempt to remove nonexistant message handler for source: " + source + " and protocol: " + protocol.getName();
			Logger.getLogger("global").log( Level.WARNING, ERROR_MESSAGE );
            System.err.println( ERROR_MESSAGE );
        }
    }
    
    
    /** get all handler associated with the protocol */
    public Set getHandlers( final Class protocol ) {
        Object protocolKey = protocolKey( protocol );
        
        if ( protocolTable.containsKey(protocolKey) ) {
            Map sourceTable = (Map)protocolTable.get(protocolKey);
            return sourceTable.entrySet();
        }
        else {
            return new HashSet();
        }
     }
    
    
    // not implemented yet
    public Set getHandlers( final Object source ) {
        return null;
    }
    
    
    /** get the handler (if any) associated with the source and protocol */
    public <T> MessageHandler<T> getHandler( final Object source, final Class<T> protocol ) {
        Object protocolKey = protocolKey( protocol );
        
        if ( protocolTable.containsKey( protocolKey ) ) {
            Map sourceTable = (Map)protocolTable.get( protocolKey );
            return (MessageHandler<T>)sourceTable.get( source );
        }
        else {
            return null;
        }
    }
    
    
    private Object protocolKey( final Class protocol ) {
        return protocol.getName();
    }
}








@@ -487,33 +487,146 @@
     
-private Map protocolTable
+/** table keyed by protocol name and mapped to the source table */%0A    final private Map%3CString,Map%3CObject,MessageHandler%3E%3E PROTOCOL_TABLE
 ;%0A%0A 
@@ -715,29 +715,30 @@
         
-protocolTable
+PROTOCOL_TABLE
  = new H
@@ -745,16 +745,51 @@
 ashtable
+%3CString,Map%3CObject,MessageHandler%3E%3E
 ();%0A    
@@ -901,32 +901,38 @@
 ler ) %7B%0A        
+final 
 Class protocol =
@@ -955,38 +955,44 @@
 ocol();%0A        
-Object
+final String
  protocolKey = p
@@ -1015,32 +1015,38 @@
 ocol );%0A        
+final 
 Object source = 
@@ -1081,21 +1081,85 @@
  Map
+%3CObject,MessageHandler%3E sourceTable;     // table of handlers keyed by
  source
-Table;
 %0A   
@@ -1173,37 +1173,38 @@
        if ( 
-protocolTable
+PROTOCOL_TABLE
 .containsKey
@@ -1249,34 +1249,30 @@
 Table = 
-(Map)protocolTable
+PROTOCOL_TABLE
 .get( pr
@@ -1346,16 +1346,39 @@
  HashMap
+%3CObject,MessageHandler%3E
 ();%0A    
@@ -1385,29 +1385,30 @@
         
-protocolTable
+PROTOCOL_TABLE
 .put( pr
@@ -1720,16 +1720,22 @@
         
+final 
 Class pr
@@ -1778,42 +1778,57 @@
     
-Object source = handler.getSource(
+final String protocolKey = protocolKey( protocol 
 );%0A 
@@ -1838,51 +1838,48 @@
     
+final 
 Object 
-protocolKey = protocolKey( protocol 
+source = handler.getSource(
 );%0A 
@@ -1895,37 +1895,38 @@
        if ( 
-protocolTable
+PROTOCOL_TABLE
 .containsKey
@@ -1949,32 +1949,38 @@
 ) %7B%0A            
+final 
 Map sourceTable 
@@ -1981,34 +1981,30 @@
 Table = 
-(Map)protocolTable
+PROTOCOL_TABLE
 .get( pr
@@ -2265,16 +2265,22 @@
         
+final 
 MessageH
@@ -2783,32 +2783,66 @@
 /%0A    public Set
+%3CMap.Entry%3CObject,MessageHandler%3E%3E
  getHandlers( fi
@@ -2864,38 +2864,44 @@
 col ) %7B%0A        
-Object
+final String
  protocolKey = p
@@ -2942,37 +2942,38 @@
        if ( 
-protocolTable
+PROTOCOL_TABLE
 .containsKey
@@ -2973,16 +2973,17 @@
 ainsKey(
+ 
 protocol
@@ -2985,16 +2985,17 @@
 tocolKey
+ 
 ) ) %7B%0A  
@@ -3008,49 +3008,75 @@
     
-Map sourceTable = (Map)protocolTable
+final Map%3CObject,MessageHandler%3E sourceTable = PROTOCOL_TABLE
 .get(
+ 
 prot
@@ -3082,16 +3082,17 @@
 tocolKey
+ 
 );%0A     
@@ -3184,16 +3184,50 @@
  HashSet
+%3CMap.Entry%3CObject,MessageHandler%3E%3E
 ();%0A    
@@ -3611,29 +3611,30 @@
    if ( 
-protocolTable
+PROTOCOL_TABLE
 .contain
@@ -3673,44 +3673,69 @@
     
-Map sourceTable = (Map)protocolTable
+final Map%3CObject,MessageHandler%3E sourceTable = PROTOCOL_TABLE
 .get
@@ -3904,22 +3904,22 @@
 private 
-Object
+String
  protoco

Use generics for tighter typing.