1 15 package org.apache.hivemind.util; 16 17 import java.util.Iterator ; 18 19 29 public class EventListenerList 30 { 31 private static final int START_SIZE = 5; 32 33 private Object [] _listeners; 34 private int _count; 35 private int _iteratorCount; 36 private int _uid; 37 38 private class ListenerIterator implements Iterator 39 { 40 private Object [] _localListeners; 41 private int _localCount; 42 private int _localUid; 43 private int _pos; 44 45 private ListenerIterator() 46 { 47 _localListeners = _listeners; 48 _localCount = _count; 49 _localUid = _uid; 50 } 51 52 public boolean hasNext() 53 { 54 if (_pos >= _localCount) 55 { 56 59 adjustIteratorCount(_localUid); 60 61 _localListeners = null; 62 _localCount = 0; 63 _localUid = -1; 64 _pos = 0; 65 66 return false; 67 } 68 69 return true; 70 } 71 72 public Object next() 73 { 74 return _localListeners[_pos++]; 75 } 76 77 public void remove() 78 { 79 throw new UnsupportedOperationException (); 80 } 81 82 } 83 84 94 public synchronized Iterator getListeners() 95 { 96 _iteratorCount++; 97 98 return new ListenerIterator(); 99 } 100 101 105 public synchronized void addListener(Object listener) 106 { 107 copyOnWrite(_count + 1); 108 109 _listeners[_count] = listener; 110 111 _count++; 112 } 113 114 120 public synchronized void removeListener(Object listener) 121 { 122 for (int i = 0; i < _count; i++) 123 { 124 if (_listeners[i] == listener) 125 { 126 removeListener(i); 127 return; 128 } 129 } 130 } 131 132 private void removeListener(int index) 133 { 134 copyOnWrite(_count); 135 136 138 _listeners[index] = _listeners[_count - 1]; 139 140 142 _listeners[_count - 1] = null; 143 144 _count--; 145 } 146 147 152 private void copyOnWrite(int requiredSize) 153 { 154 int size = _listeners == null ? 0 : _listeners.length; 155 156 if (_iteratorCount > 0 || size < requiredSize) 157 { 158 int nominalSize = (size == 0) ? START_SIZE : 2 * size; 159 160 if (size >= requiredSize) 162 { 163 nominalSize = size; 164 } 165 166 int newSize = Math.max(requiredSize, nominalSize); 167 168 Object [] newListeners = new Object [newSize]; 169 170 if (_count > 0) 171 System.arraycopy(_listeners, 0, newListeners, 0, _count); 172 173 _listeners = newListeners; 174 175 _iteratorCount = 0; 177 _uid++; 178 } 179 } 180 181 private synchronized void adjustIteratorCount(int iteratorUid) 182 { 183 if (_uid == iteratorUid) 184 _iteratorCount--; 185 } 186 } 187 | Popular Tags |