1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package org.apache.harmony.awt; 19 20 import java.io.IOException; 21 import java.io.ObjectInputStream; 22 import java.io.ObjectOutputStream; 23 import java.io.Serializable; 24 import java.util.ArrayList; 25 import java.util.Collections; 26 import java.util.EventListener; 27 import java.util.Iterator; 28 import java.util.List; 29 30 /** 31 * List of AWT listeners. It is for 3 purposes. 32 * 1. To support list modification from listeners 33 * 2. To ensure call for all listeners as atomic operation 34 * 3. To support system listeners that are needed for built-in AWT components 35 */ 36 public class ListenerList<T extends EventListener> implements Serializable { 37 private static final long serialVersionUID = 9180703263299648154L; 38 39 private transient ArrayList<T> systemList; 40 private transient ArrayList<T> userList; 41 42 public ListenerList() { 43 super(); 44 } 45 46 /** 47 * Adds system listener to this list. 48 * 49 * @param listener - listener to be added. 50 */ 51 public void addSystemListener(T listener) { 52 if (systemList == null) { 53 systemList = new ArrayList<T>(); 54 } 55 systemList.add(listener); 56 } 57 58 /** 59 * Adds user (public) listener to this list. 60 * 61 * @param listener - listener to be added. 62 */ 63 public void addUserListener(T listener) { 64 if (listener == null) { 65 return; 66 } 67 // transactionally replace old list 68 synchronized (this) { 69 if (userList == null) { 70 userList = new ArrayList<T>(); 71 userList.add(listener); 72 return; 73 } 74 ArrayList<T> newList = new ArrayList<T>(userList); 75 newList.add(listener); 76 userList = newList; 77 } 78 } 79 80 /** 81 * Removes user (public) listener to this list. 82 * 83 * @param listener - listener to be removed. 84 */ 85 public void removeUserListener(Object listener) { 86 if (listener == null) { 87 return; 88 } 89 // transactionally replace old list 90 synchronized (this) { 91 if (userList == null || !userList.contains(listener)) { 92 return; 93 } 94 ArrayList<T> newList = new ArrayList<T>(userList); 95 newList.remove(listener); 96 userList = (newList.size() > 0 ? newList : null); 97 } 98 } 99 100 /** 101 * Gets all user (public) listeners in one array. 102 * 103 * @param emptyArray - empty array, it's for deriving particular listeners class. 104 * @return array of all user listeners. 105 */ 106 public <AT> AT[] getUserListeners(AT[] emptyArray){ 107 synchronized (this) { 108 return (userList != null ? userList.toArray(emptyArray) : emptyArray); 109 110 } 111 } 112 113 /** 114 * Gets all user (public) listeners in one list. 115 * 116 * @return list of all user listeners. 117 */ 118 public List<T> getUserListeners() { 119 synchronized (this) { 120 if (userList == null || userList.isEmpty()) { 121 return Collections.emptyList(); 122 } 123 return new ArrayList<T>(userList); 124 } 125 } 126 127 public List<T> getSystemListeners() { 128 synchronized (this) { 129 if (systemList == null || systemList.isEmpty()) { 130 return Collections.emptyList(); 131 } 132 return new ArrayList<T>(systemList); 133 } 134 } 135 136 /** 137 * Gets iterator for user listeners. 138 * 139 * @return iterator for user listeners. 140 */ 141 public Iterator<T> getUserIterator() { 142 synchronized (this) { 143 if (userList == null) { 144 List<T> emptyList = Collections.emptyList(); 145 return emptyList.iterator(); 146 } 147 return new ReadOnlyIterator<T>(userList.iterator()); 148 } 149 } 150 151 /** 152 * Gets iterator for system listeners. 153 * 154 * @return iterator for system listeners. 155 */ 156 public Iterator<T> getSystemIterator() { 157 return systemList.iterator(); 158 } 159 160 private static ArrayList<?> getOnlySerializable(ArrayList<?> list) { 161 if (list == null) { 162 return null; 163 } 164 165 ArrayList<Object> result = new ArrayList<Object>(); 166 for (Iterator<?> it = list.iterator(); it.hasNext();) { 167 Object obj = it.next(); 168 if (obj instanceof Serializable) { 169 result.add(obj); 170 } 171 } 172 173 return (result.size() != 0) ? result : null; 174 } 175 176 private void writeObject(ObjectOutputStream stream) throws IOException { 177 178 stream.defaultWriteObject(); 179 180 stream.writeObject(getOnlySerializable(systemList)); 181 stream.writeObject(getOnlySerializable(userList)); 182 } 183 184 @SuppressWarnings("unchecked") 185 private void readObject(ObjectInputStream stream) 186 throws IOException, ClassNotFoundException { 187 188 stream.defaultReadObject(); 189 190 systemList = (ArrayList<T>)stream.readObject(); 191 userList = (ArrayList<T>)stream.readObject(); 192 } 193 194 } 195