1 8 package org.apache.avalon.excalibur.command; 9 10 import org.apache.avalon.excalibur.collections.Buffer; 11 import org.apache.avalon.excalibur.collections.VariableSizeBuffer; 12 import org.apache.avalon.excalibur.concurrent.Mutex; 13 import org.apache.avalon.excalibur.event.DefaultQueue; 14 import org.apache.avalon.excalibur.event.EventHandler; 15 import org.apache.avalon.excalibur.event.Queue; 16 import org.apache.avalon.excalibur.event.QueueElement; 17 import org.apache.avalon.excalibur.event.Signal; 18 import org.apache.avalon.excalibur.event.Sink; 19 20 import java.util.ArrayList ; 21 import java.util.Collections ; 22 import java.util.HashMap ; 23 import java.util.Iterator ; 24 import java.util.Map ; 25 26 34 public class CommandManager implements EventPipeline 35 { 36 private final Queue m_queue = new DefaultQueue(); 37 private final HashMap m_signalHandlers = new HashMap (); 38 private final Mutex m_mutex = new Mutex(); 39 private final EventHandler m_eventHandler = new CommandEventHandler( 40 Collections.unmodifiableMap( m_signalHandlers ) ); 41 private final Sink[] m_sinks = new Sink[] { m_queue }; 42 43 public CommandManager() 44 { 45 } 46 47 public final Queue getCommandQueue() 48 { 49 return m_queue; 50 } 51 52 public final void registerSignalHandler( Signal signal, EventHandler handler ) 53 { 54 try 55 { 56 m_mutex.acquire(); 57 ArrayList handlers = (ArrayList ) m_signalHandlers.get( signal.getClass() ); 58 59 if ( null == handlers ) 60 { 61 handlers = new ArrayList (); 62 } 63 64 if ( ! handlers.contains( handler ) ) 65 { 66 handlers.add( handler ); 67 68 m_signalHandlers.put( signal.getClass(), handlers ); 69 } 70 } 71 catch (InterruptedException ie) 72 { 73 } 75 finally 76 { 77 m_mutex.release(); 78 } 79 } 80 81 public final void deregisterSignalHandler( Signal signal, EventHandler handler ) 82 { 83 try 84 { 85 m_mutex.acquire(); 86 ArrayList handlers = (ArrayList ) m_signalHandlers.get( signal.getClass() ); 87 88 if ( null != handlers ) 89 { 90 if ( handlers.remove( handler ) ) 91 { 92 m_signalHandlers.put( signal.getClass(), handlers ); 93 } 94 95 if ( 0 == handlers.size() ) 96 { 97 m_signalHandlers.remove( signal.getClass() ); 98 } 99 } 100 } 101 catch (InterruptedException ie) 102 { 103 } 105 finally 106 { 107 m_mutex.release(); 108 } 109 } 110 111 public final Sink[] getSinks() 112 { 113 return m_sinks; 114 } 115 116 public final EventHandler getEventHandler() 117 { 118 return m_eventHandler; 119 } 120 121 private final static class CommandEventHandler implements EventHandler 122 { 123 private final Map m_signalHandlers; 124 private final Buffer m_delayedCommands = new VariableSizeBuffer(); 125 126 protected CommandEventHandler( Map signalHandlers ) 127 { 128 m_signalHandlers = signalHandlers; 129 } 130 131 public final void handleEvents( QueueElement[] elements ) 132 { 133 for (int i = 0; i < elements.length; i++) 134 { 135 handleEvent( elements[i] ); 136 } 137 138 int size = m_delayedCommands.size(); 139 for (int i = 0; i < size; i++) 140 { 141 DelayedCommandInfo command = (DelayedCommandInfo) m_delayedCommands.remove(); 142 143 if ( System.currentTimeMillis() >= command.m_nextRunTime ) 144 { 145 try 146 { 147 command.m_command.execute(); 148 } catch (Exception e) 149 { 150 } 152 153 command.m_numExecutions++; 154 155 if ( command.m_repeatable ) 156 { 157 RepeatedCommand cmd = (RepeatedCommand) command.m_command; 158 int numRepeats = cmd.getNumberOfRepeats(); 159 160 if ( numRepeats < 1 || numRepeats < command.m_numExecutions ) 161 { 162 command.m_nextRunTime = System.currentTimeMillis() + 163 cmd.getRepeatInterval(); 164 m_delayedCommands.add( command ); 165 } 166 } 167 } 168 } 169 } 170 171 public final void handleEvent( QueueElement element ) 172 { 173 if ( ! ( element instanceof Signal ) ) 174 { 175 return; 176 } 177 178 if ( ! ( element instanceof Command ) ) 179 { 180 ArrayList handlers = (ArrayList ) m_signalHandlers.get( element.getClass() ); 181 182 if ( null != handlers ) 183 { 184 Iterator i = handlers.iterator(); 185 186 while ( i.hasNext() ) 187 { 188 EventHandler handler = (EventHandler) i.next(); 189 handler.handleEvent( element ); 190 } 191 } 192 193 return; 194 } 195 196 if ( element instanceof DelayedCommand ) 197 { 198 DelayedCommandInfo commandInfo = new DelayedCommandInfo(); 199 commandInfo.m_command = (DelayedCommand) element; 200 commandInfo.m_nextRunTime = System.currentTimeMillis() + 201 commandInfo.m_command.getDelayInterval(); 202 commandInfo.m_numExecutions = 0; 203 commandInfo.m_repeatable = element instanceof RepeatedCommand; 204 205 m_delayedCommands.add( commandInfo ); 206 return; 207 } 208 209 try 210 { 211 ((Command) element).execute(); 212 } catch (Exception e) 213 { 214 } 216 } 217 } 218 219 private final static class DelayedCommandInfo 220 { 221 protected DelayedCommand m_command; 222 protected long m_nextRunTime; 223 protected int m_numExecutions; 224 protected boolean m_repeatable; 225 } 226 } | Popular Tags |