| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.harmony.awt; |
| |
| import java.io.IOException; |
| import java.io.ObjectInputStream; |
| import java.io.ObjectOutputStream; |
| import java.io.Serializable; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.EventListener; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| /** |
| * List of AWT listeners. It is for 3 purposes. |
| * 1. To support list modification from listeners |
| * 2. To ensure call for all listeners as atomic operation |
| * 3. To support system listeners that are needed for built-in AWT components |
| */ |
| public class ListenerList<T extends EventListener> implements Serializable { |
| private static final long serialVersionUID = 9180703263299648154L; |
| |
| private transient ArrayList<T> systemList; |
| private transient ArrayList<T> userList; |
| |
| public ListenerList() { |
| super(); |
| } |
| |
| /** |
| * Adds system listener to this list. |
| * |
| * @param listener - listener to be added. |
| */ |
| public void addSystemListener(T listener) { |
| if (systemList == null) { |
| systemList = new ArrayList<T>(); |
| } |
| systemList.add(listener); |
| } |
| |
| /** |
| * Adds user (public) listener to this list. |
| * |
| * @param listener - listener to be added. |
| */ |
| public void addUserListener(T listener) { |
| if (listener == null) { |
| return; |
| } |
| // transactionally replace old list |
| synchronized (this) { |
| if (userList == null) { |
| userList = new ArrayList<T>(); |
| userList.add(listener); |
| return; |
| } |
| ArrayList<T> newList = new ArrayList<T>(userList); |
| newList.add(listener); |
| userList = newList; |
| } |
| } |
| |
| /** |
| * Removes user (public) listener to this list. |
| * |
| * @param listener - listener to be removed. |
| */ |
| public void removeUserListener(Object listener) { |
| if (listener == null) { |
| return; |
| } |
| // transactionally replace old list |
| synchronized (this) { |
| if (userList == null || !userList.contains(listener)) { |
| return; |
| } |
| ArrayList<T> newList = new ArrayList<T>(userList); |
| newList.remove(listener); |
| userList = (newList.size() > 0 ? newList : null); |
| } |
| } |
| |
| /** |
| * Gets all user (public) listeners in one array. |
| * |
| * @param emptyArray - empty array, it's for deriving particular listeners class. |
| * @return array of all user listeners. |
| */ |
| public <AT> AT[] getUserListeners(AT[] emptyArray){ |
| synchronized (this) { |
| return (userList != null ? userList.toArray(emptyArray) : emptyArray); |
| |
| } |
| } |
| |
| /** |
| * Gets all user (public) listeners in one list. |
| * |
| * @return list of all user listeners. |
| */ |
| public List<T> getUserListeners() { |
| synchronized (this) { |
| if (userList == null || userList.isEmpty()) { |
| return Collections.emptyList(); |
| } |
| return new ArrayList<T>(userList); |
| } |
| } |
| |
| public List<T> getSystemListeners() { |
| synchronized (this) { |
| if (systemList == null || systemList.isEmpty()) { |
| return Collections.emptyList(); |
| } |
| return new ArrayList<T>(systemList); |
| } |
| } |
| |
| /** |
| * Gets iterator for user listeners. |
| * |
| * @return iterator for user listeners. |
| */ |
| public Iterator<T> getUserIterator() { |
| synchronized (this) { |
| if (userList == null) { |
| List<T> emptyList = Collections.emptyList(); |
| return emptyList.iterator(); |
| } |
| return new ReadOnlyIterator<T>(userList.iterator()); |
| } |
| } |
| |
| /** |
| * Gets iterator for system listeners. |
| * |
| * @return iterator for system listeners. |
| */ |
| public Iterator<T> getSystemIterator() { |
| return systemList.iterator(); |
| } |
| |
| private static ArrayList<?> getOnlySerializable(ArrayList<?> list) { |
| if (list == null) { |
| return null; |
| } |
| |
| ArrayList<Object> result = new ArrayList<Object>(); |
| for (Iterator<?> it = list.iterator(); it.hasNext();) { |
| Object obj = it.next(); |
| if (obj instanceof Serializable) { |
| result.add(obj); |
| } |
| } |
| |
| return (result.size() != 0) ? result : null; |
| } |
| |
| private void writeObject(ObjectOutputStream stream) throws IOException { |
| |
| stream.defaultWriteObject(); |
| |
| stream.writeObject(getOnlySerializable(systemList)); |
| stream.writeObject(getOnlySerializable(userList)); |
| } |
| |
| @SuppressWarnings("unchecked") |
| private void readObject(ObjectInputStream stream) |
| throws IOException, ClassNotFoundException { |
| |
| stream.defaultReadObject(); |
| |
| systemList = (ArrayList<T>)stream.readObject(); |
| userList = (ArrayList<T>)stream.readObject(); |
| } |
| |
| } |