Home | History | Annotate | Download | only in awt
      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