1 36 package org.ungoverned.oscar.util; 37 38 import java.util.ArrayList ; 39 import java.util.EventListener ; 40 import java.util.EventObject ; 41 42 import org.ungoverned.oscar.Oscar; 43 44 71 public class DispatchQueue 72 { 73 private static final Object [] m_emptyList = new Object [0]; 75 76 private Object [] m_listeners = m_emptyList; 78 79 private static Thread m_thread = null; 81 private static String m_threadLock = "thread lock"; 82 private static boolean m_stopping = false; 83 private static boolean m_stopped = false; 84 85 private static final ArrayList m_requestList = new ArrayList (); 87 private static final ArrayList m_requestCache = new ArrayList (); 89 90 94 public DispatchQueue() 95 { 96 synchronized (m_threadLock) 97 { 98 if (m_thread == null) 100 { 101 m_thread = new Thread (new Runnable () { 102 public void run() 103 { 104 DispatchQueue.run(); 105 } 106 }, "OscarDispatchQueue"); 107 m_thread.start(); 108 } 109 } 110 } 111 112 120 public static void shutdown() 121 { 122 synchronized (m_threadLock) 123 { 124 if (m_stopped) 126 { 127 return; 128 } 129 130 m_stopping = true; 132 synchronized (m_requestList) 133 { 134 m_requestList.notify(); 135 } 136 137 while (!m_stopped) 139 { 140 try { 141 m_threadLock.wait(); 142 } catch (InterruptedException ex) { 143 } 144 } 145 } 146 } 147 148 157 public Object [] getListeners() 158 { 159 return m_listeners; 160 } 161 162 169 public EventListener getListener(Class clazz, EventListener l) 170 { 171 if (l == null) 173 { 174 throw new IllegalArgumentException ("Listener is null"); 175 } 176 else if (!clazz.isInstance(l)) 177 { 178 throw new IllegalArgumentException ( 179 "Listener not of type " + clazz.getName()); 180 } 181 182 synchronized (this) 184 { 185 int idx = -1; 187 for (int i = 0; i < m_listeners.length; i += 2) 188 { 189 if ((m_listeners[i] == clazz) && 190 (m_listeners[i + 1].equals(l))) 191 { 192 return (EventListener ) m_listeners[i + 1]; 193 } 194 } 195 } 196 197 return null; 198 } 199 200 207 public void addListener(Class clazz, EventListener l) 208 { 209 if (l == null) 211 { 212 throw new IllegalArgumentException ("Listener is null"); 213 } 214 else if (!clazz.isInstance(l)) 215 { 216 throw new IllegalArgumentException ( 217 "Listener not of type " + clazz.getName()); 218 } 219 220 synchronized (this) 222 { 223 if (m_listeners == m_emptyList) 225 { 226 m_listeners = new Object [] { clazz, l }; 227 } 228 else 234 { 235 Object [] newList = new Object [m_listeners.length + 2]; 236 System.arraycopy(m_listeners, 0, newList, 0, m_listeners.length); 237 newList[m_listeners.length] = clazz; 238 newList[m_listeners.length + 1] = l; 239 m_listeners = newList; 240 } 241 } 242 } 243 244 251 public void removeListener(Class clazz, EventListener l) 252 { 253 if (l == null) 255 { 256 throw new IllegalArgumentException ("Listener is null"); 257 } 258 else if (!clazz.isInstance(l)) 259 { 260 throw new IllegalArgumentException ( 261 "Listener not of type " + clazz.getName()); 262 } 263 264 synchronized (this) 266 { 267 int idx = -1; 269 for (int i = 0; i < m_listeners.length; i += 2) 270 { 271 if ((m_listeners[i] == clazz) && 272 (m_listeners[i + 1].equals(l))) 273 { 274 idx = i; 275 break; 276 } 277 } 278 279 if (idx >= 0) 281 { 282 if ((m_listeners.length - 2) == 0) 284 { 285 m_listeners = m_emptyList; 286 } 287 else 293 { 294 Object [] newList = new Object [m_listeners.length - 2]; 295 System.arraycopy(m_listeners, 0, newList, 0, idx); 296 if (idx < newList.length) 297 { 298 System.arraycopy(m_listeners, idx + 2, newList, idx, 299 newList.length - idx); 300 } 301 m_listeners = newList; 302 } 303 } 304 } 305 } 306 307 317 public void dispatch(Dispatcher d, Class clazz, EventObject eventObj) 318 { 319 dispatch(m_listeners, d, clazz, eventObj); 320 } 321 322 protected void dispatch( 323 Object [] listeners, Dispatcher d, Class clazz, EventObject eventObj) 324 { 325 if (m_stopped) 327 { 328 return; 329 } 330 331 DispatchRequest dr = null; 334 synchronized (m_requestCache) 335 { 336 if (m_requestCache.size() > 0) 337 dr = (DispatchRequest) m_requestCache.remove(0); 338 else 339 dr = new DispatchRequest(); 340 } 341 342 dr.m_listeners = listeners; 344 dr.m_dispatcher = d; 345 dr.m_clazz = clazz; 346 dr.m_eventObj = eventObj; 347 348 synchronized (m_requestList) 350 { 351 m_requestList.add(dr); 353 m_requestList.notify(); 356 } 357 } 358 359 private static void run() 360 { 361 DispatchRequest dr = null; 362 while (true) 363 { 364 synchronized (m_requestList) 367 { 368 while ((m_requestList.size() == 0) && !m_stopping) 372 { 373 try { 375 m_requestList.wait(); 376 } catch (InterruptedException ex) { 377 Oscar.error("Dispatch thread error.", ex); 378 } 379 } 380 381 if ((m_requestList.size() == 0) && (m_stopping)) 384 { 385 synchronized (m_threadLock) 386 { 387 m_stopped = true; 388 m_threadLock.notifyAll(); 389 } 390 return; 391 } 392 393 dr = (DispatchRequest) m_requestList.remove(0); 395 } 396 397 401 if (dr.m_listeners.length > 0) 403 { 404 for (int i = dr.m_listeners.length - 2; i >= 0; i -= 2) 406 { 407 if (dr.m_listeners[i] == dr.m_clazz) 408 { 409 try { 410 dr.m_dispatcher.dispatch( 411 (EventListener ) dr.m_listeners[i + 1], dr.m_eventObj); 412 } catch (Throwable th) { 413 Oscar.error("DispatchQueue: Error during dispatch.", th); 414 } 415 } 416 } 417 } 418 419 synchronized (m_requestCache) 421 { 422 m_requestCache.add(dr); 423 } 424 } 425 } 426 427 private static class DispatchRequest 428 { 429 public Object [] m_listeners = null; 430 public Dispatcher m_dispatcher = null; 431 public Class m_clazz = null; 432 public EventObject m_eventObj = null; 433 } 434 } | Popular Tags |