001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.harmony.awt;
019:
020: import java.io.IOException;
021: import java.io.ObjectInputStream;
022: import java.io.ObjectOutputStream;
023: import java.io.Serializable;
024: import java.util.ArrayList;
025: import java.util.Collections;
026: import java.util.EventListener;
027: import java.util.Iterator;
028: import java.util.List;
029:
030: /**
031: * List of AWT listeners. It is for 3 purposes.
032: * 1. To support list modification from listeners
033: * 2. To ensure call for all listeners as atomic operation
034: * 3. To support system listeners that are needed for built-in AWT components
035: */
036: public class ListenerList<T extends EventListener> implements
037: Serializable {
038: private static final long serialVersionUID = 9180703263299648154L;
039:
040: private transient ArrayList<T> systemList;
041: private transient ArrayList<T> userList;
042:
043: public ListenerList() {
044: super ();
045: }
046:
047: /**
048: * Adds system listener to this list.
049: *
050: * @param listener - listener to be added.
051: */
052: public void addSystemListener(T listener) {
053: if (systemList == null) {
054: systemList = new ArrayList<T>();
055: }
056: systemList.add(listener);
057: }
058:
059: /**
060: * Adds user (public) listener to this list.
061: *
062: * @param listener - listener to be added.
063: */
064: public void addUserListener(T listener) {
065: if (listener == null) {
066: return;
067: }
068: // transactionally replace old list
069: synchronized (this ) {
070: if (userList == null) {
071: userList = new ArrayList<T>();
072: userList.add(listener);
073: return;
074: }
075: ArrayList<T> newList = new ArrayList<T>(userList);
076: newList.add(listener);
077: userList = newList;
078: }
079: }
080:
081: /**
082: * Removes user (public) listener to this list.
083: *
084: * @param listener - listener to be removed.
085: */
086: public void removeUserListener(Object listener) {
087: if (listener == null) {
088: return;
089: }
090: // transactionally replace old list
091: synchronized (this ) {
092: if (userList == null || !userList.contains(listener)) {
093: return;
094: }
095: ArrayList<T> newList = new ArrayList<T>(userList);
096: newList.remove(listener);
097: userList = (newList.size() > 0 ? newList : null);
098: }
099: }
100:
101: /**
102: * Gets all user (public) listeners in one array.
103: *
104: * @param emptyArray - empty array, it's for deriving particular listeners class.
105: * @return array of all user listeners.
106: */
107: public <AT> AT[] getUserListeners(AT[] emptyArray) {
108: synchronized (this ) {
109: return (userList != null ? userList.toArray(emptyArray)
110: : emptyArray);
111:
112: }
113: }
114:
115: /**
116: * Gets all user (public) listeners in one list.
117: *
118: * @return list of all user listeners.
119: */
120: public List<T> getUserListeners() {
121: synchronized (this ) {
122: if (userList == null || userList.isEmpty()) {
123: return Collections.emptyList();
124: }
125: return new ArrayList<T>(userList);
126: }
127: }
128:
129: public List<T> getSystemListeners() {
130: synchronized (this ) {
131: if (systemList == null || systemList.isEmpty()) {
132: return Collections.emptyList();
133: }
134: return new ArrayList<T>(systemList);
135: }
136: }
137:
138: /**
139: * Gets iterator for user listeners.
140: *
141: * @return iterator for user listeners.
142: */
143: public Iterator<T> getUserIterator() {
144: synchronized (this ) {
145: if (userList == null) {
146: List<T> emptyList = Collections.emptyList();
147: return emptyList.iterator();
148: }
149: return new ReadOnlyIterator<T>(userList.iterator());
150: }
151: }
152:
153: /**
154: * Gets iterator for system listeners.
155: *
156: * @return iterator for system listeners.
157: */
158: public Iterator<T> getSystemIterator() {
159: return systemList.iterator();
160: }
161:
162: private static ArrayList<?> getOnlySerializable(ArrayList<?> list) {
163: if (list == null) {
164: return null;
165: }
166:
167: ArrayList<Object> result = new ArrayList<Object>();
168: for (Iterator<?> it = list.iterator(); it.hasNext();) {
169: Object obj = it.next();
170: if (obj instanceof Serializable) {
171: result.add(obj);
172: }
173: }
174:
175: return (result.size() != 0) ? result : null;
176: }
177:
178: private void writeObject(ObjectOutputStream stream)
179: throws IOException {
180:
181: stream.defaultWriteObject();
182:
183: stream.writeObject(getOnlySerializable(systemList));
184: stream.writeObject(getOnlySerializable(userList));
185: }
186:
187: @SuppressWarnings("unchecked")
188: private void readObject(ObjectInputStream stream)
189: throws IOException, ClassNotFoundException {
190:
191: stream.defaultReadObject();
192:
193: systemList = (ArrayList<T>) stream.readObject();
194: userList = (ArrayList<T>) stream.readObject();
195: }
196:
197: }
|