KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > excalibur > command > CommandManager


1 /*
2  * Copyright (C) The Apache Software Foundation. All rights reserved.
3  *
4  * This software is published under the terms of the Apache Software License
5  * version 1.1, a copy of which has been included with this distribution in
6  * the LICENSE.txt file.
7  */

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 JavaDoc;
21 import java.util.Collections JavaDoc;
22 import java.util.HashMap JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.Map JavaDoc;
25
26 /**
27  * The CommandManager handles asynchronous commands from the rest of the system.
28  * The only exposed piece is the Queue that other components use to give Commands
29  * to this system. You <strong>must</strong> register this with a ThreadManager
30  * for it to work.
31  *
32  * @author <a HREF="mailto:bloritsch@apache.org">Berin Loritsch</a>
33  */

34 public class CommandManager implements EventPipeline
35 {
36     private final Queue m_queue = new DefaultQueue();
37     private final HashMap JavaDoc m_signalHandlers = new HashMap JavaDoc();
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 JavaDoc handlers = (ArrayList JavaDoc) m_signalHandlers.get( signal.getClass() );
58
59             if ( null == handlers )
60             {
61                 handlers = new ArrayList JavaDoc();
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 JavaDoc ie)
72         {
73             // ignore for now
74
}
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 JavaDoc handlers = (ArrayList JavaDoc) 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 JavaDoc ie)
102         {
103             // ignore for now
104
}
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 JavaDoc m_signalHandlers;
124         private final Buffer m_delayedCommands = new VariableSizeBuffer();
125
126         protected CommandEventHandler( Map JavaDoc 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 JavaDoc e)
149                     {
150                         // ignore for now
151
}
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 JavaDoc handlers = (ArrayList JavaDoc) m_signalHandlers.get( element.getClass() );
181
182                 if ( null != handlers )
183                 {
184                     Iterator JavaDoc 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 JavaDoc e)
213             {
214                 // ignore for now
215
}
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