/* * 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(); } }