001 /* 002 003 ============================================================================ 004 The Apache Software License, Version 1.1 005 ============================================================================ 006 007 Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. 008 009 Redistribution and use in source and binary forms, with or without modifica- 010 tion, are permitted provided that the following conditions are met: 011 012 1. Redistributions of source code must retain the above copyright notice, 013 this list of conditions and the following disclaimer. 014 015 2. Redistributions in binary form must reproduce the above copyright notice, 016 this list of conditions and the following disclaimer in the documentation 017 and/or other materials provided with the distribution. 018 019 3. The end-user documentation included with the redistribution, if any, must 020 include the following acknowledgment: "This product includes software 021 developed by the Apache Software Foundation (http://www.apache.org/)." 022 Alternately, this acknowledgment may appear in the software itself, if 023 and wherever such third-party acknowledgments normally appear. 024 025 4. The names "Batik" and "Apache Software Foundation" must not be 026 used to endorse or promote products derived from this software without 027 prior written permission. For written permission, please contact 028 apache@apache.org. 029 030 5. Products derived from this software may not be called "Apache", nor may 031 "Apache" appear in their name, without prior written permission of the 032 Apache Software Foundation. 033 034 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, 035 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 036 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 037 APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 038 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- 039 DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 040 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 041 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 042 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 043 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 044 045 This software consists of voluntary contributions made by many individuals 046 on behalf of the Apache Software Foundation. For more information on the 047 Apache Software Foundation, please see <http://www.apache.org/>. 048 049 */ 050 051 package org.apache.batik.util; 052 053 import java.awt.EventQueue; 054 import java.util.List; 055 import java.lang.reflect.InvocationTargetException; 056 057 /** 058 * Generic class to dispatch events in a highly relyable way 059 * 060 * @author <a href="mailto:deweese@apache.org>l449433</a> 061 * @version $Id: EventDispatcher.java,v 1.3 2003/09/16 01:12:53 deweese Exp $ 062 */ 063 public class EventDispatcher { 064 065 public interface Dispatcher { 066 public void dispatch(Object listener, 067 Object event); 068 } 069 070 071 public static void fireEvent(final Dispatcher dispatcher, 072 final List listeners, 073 final Object evt, 074 final boolean useEventQueue) { 075 if (useEventQueue && !EventQueue.isDispatchThread()) { 076 Runnable r = new Runnable() { 077 public void run() { 078 fireEvent(dispatcher, listeners, evt, useEventQueue); 079 } 080 }; 081 try { 082 EventQueue.invokeAndWait(r); 083 } catch (InvocationTargetException e) { 084 e.printStackTrace(); 085 } catch (InterruptedException e) { 086 // Assume they will get delivered???? 087 // be nice to wait on List but how??? 088 } catch (ThreadDeath td) { 089 throw td; 090 } catch (Throwable t) { 091 t.printStackTrace(); 092 } 093 return; 094 } 095 096 Object [] ll = null; 097 Throwable err = null; 098 int retryCount = 10; 099 while (--retryCount != 0) { 100 // If the thread has been interrupted this can 'mess up' 101 // the class loader and cause this otherwise safe code to 102 // throw errors. 103 try { 104 synchronized (listeners) { 105 if (listeners.size() == 0) 106 return; Rate107 ll = listeners.toArray(); 108 break; 109 } 110 } catch(Throwable t) { 111 err = t; 112 } 113 } 114 if (ll == null) { 115 if (err != null) 116 err.printStackTrace(); 117 return; 118 } 119 dispatchEvent(dispatcher, ll, evt); 120 } 121 122 protected static void dispatchEvent(final Dispatcher dispatcher, 123 final Object [] ll, 124 final Object evt) { 125 ThreadDeath td = null; 126 try { 127 for (int i = 0; i < ll.length; i++) { 128 try { 129 Object l; 130 synchronized (ll) { 131 l = ll[i]; 132 if (l == null) continue; 133 ll[i] = null; 134 } 135 dispatcher.dispatch(l, evt); 136 } catch (ThreadDeath t) { 137 // Keep delivering messages but remember to throw later. 138 td = t; 139 } catch (Throwable t) { 140 t.printStackTrace(); 141 } 142 } 143 } catch (ThreadDeath t) { 144 // Remember to throw later. 145 td = t; 146 } catch (Throwable t) { 147 if (ll[ll.length-1] != null) 148 dispatchEvent(dispatcher, ll, evt); 149 t.printStackTrace(); 150 } 151 if (td != null) throw td; 152 } 153 }