1 /*
2  * Created on 1 Nov 2006
3  * Created by Paul Gardner
4  * Copyright (C) Azureus Software, Inc, All Rights Reserved.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17  *
18  */
19 
20 
21 package org.gudy.azureus2.core3.util;
22 
23 import java.lang.ref.WeakReference;
24 import java.util.*;
25 
26 public class
27 DebugWeakList
28 {
29 	final static boolean DEBUG = Constants.isCVSVersion();
30 
31 	private String		name;
32 	private List		list;
33 
34 	public
DebugWeakList( String _name )35 	DebugWeakList(
36 		String	_name )
37 	{
38 		name	= _name;
39 		list	= new ArrayList();
40 	}
41 
42 	public
DebugWeakList( String _name, DebugWeakList l )43 	DebugWeakList(
44 		String			_name,
45 		DebugWeakList	l )
46 	{
47 		name	= _name;
48 		list 	= new ArrayList( l.list );
49 	}
50 
51 	public void
add( Object obj )52 	add(
53 		Object		obj )
54 	{
55 		if ( DEBUG ){
56 
57 			list.add( new Object[]{ obj.getClass(), new WeakReference( obj )});
58 
59 		}else{
60 
61 			list.add( obj );
62 		}
63 	}
64 
65 	public void
remove( Object obj )66 	remove(
67 		Object		obj )
68 	{
69 		if ( DEBUG ){
70 
71 			Iterator	it = list.iterator();
72 
73 			while( it.hasNext()){
74 
75 				Object[]	entry  = (Object[])it.next();
76 
77 				WeakReference	wr = (WeakReference)entry[1];
78 
79 				Object	target = wr.get();
80 
81 				if ( target == null ){
82 
83 					it.remove();
84 
85 					logRemoved((Class)entry[0]);
86 
87 				}else if ( target == obj ){
88 
89 					it.remove();
90 
91 					return;
92 				}
93 			}
94 		}else{
95 
96 			list.remove( obj );
97 		}
98 	}
99 
100 	public boolean
contains( Object obj )101 	contains(
102 		Object	obj )
103 	{
104 		if ( DEBUG ){
105 
106 			Iterator	it = list.iterator();
107 
108 			while( it.hasNext()){
109 
110 				Object[]	entry  = (Object[])it.next();
111 
112 				WeakReference	wr = (WeakReference)entry[1];
113 
114 				Object	target = wr.get();
115 
116 				if ( target == null ){
117 
118 					it.remove();
119 
120 					logRemoved((Class)entry[0]);
121 
122 				}else if ( target == obj ){
123 
124 					return( true );
125 				}
126 			}
127 
128 			return( false );
129 		}else{
130 
131 			return( list.contains( obj ));
132 		}
133 	}
134 
135 	protected void
logRemoved( Class cla )136 	logRemoved(
137 		Class	cla )
138 	{
139 		Debug.out( "Object '" + cla + "' was not removed correctly from " + name );
140 	}
141 
142 	public Iterator
iterator()143 	iterator()
144 	{
145 		if ( DEBUG ){
146 
147 			return( new WeakListIterator());
148 
149 		}else{
150 
151 			return( list.iterator());
152 		}
153 	}
154 
155 	public int
estimatedSize()156 	estimatedSize()
157 	{
158 		return( list.size());
159 	}
160 
161 	protected class
162 	WeakListIterator
163 		implements Iterator
164 	{
165 		private Iterator	it = list.iterator();
166 
167 		private Object	pending_result;
168 		private Object	last_result;
169 
170 		public boolean
hasNext()171 		hasNext()
172 		{
173 			if ( pending_result != null ){
174 
175 				return( true );
176 			}
177 
178 			while( it.hasNext()){
179 
180 				Object[]	entry  = (Object[])it.next();
181 
182 				WeakReference	wr = (WeakReference)entry[1];
183 
184 				Object	target = wr.get();
185 
186 				if ( target == null ){
187 
188 					it.remove();
189 
190 					logRemoved((Class)entry[0]);
191 
192 				}else{
193 
194 					pending_result = target;
195 
196 					return( true );
197 				}
198 			}
199 
200 			return( false );
201 		}
202 
203 		public Object
next()204 		next()
205 
206 			throws NoSuchElementException
207 		{
208 			if ( pending_result == null ){
209 
210 				hasNext();
211 			}
212 
213 			if ( pending_result == null ){
214 
215 				throw( new NoSuchElementException());
216 			}
217 
218 			last_result = pending_result;
219 
220 			pending_result = null;
221 
222 			return( last_result );
223 		}
224 
225 		public void
remove()226 		remove()
227 		{
228 			Object	lr = last_result;
229 
230 			if ( lr == null ){
231 
232 				throw( new NoSuchElementException());
233 			}
234 
235 			last_result	= null;
236 
237 			if ( pending_result == null ){
238 
239 				it.remove();
240 
241 			}else{
242 
243 					// has next has skipped on beyond last result, need to manually fix up...
244 
245 				Iterator	temp_it = list.iterator();
246 
247 				while( temp_it.hasNext()){
248 
249 					Object[]	entry  = (Object[])temp_it.next();
250 
251 					WeakReference	wr = (WeakReference)entry[1];
252 
253 					Object	target = wr.get();
254 
255 					if ( target == lr ){
256 
257 						it = temp_it;
258 
259 						it.remove();
260 
261 						return;
262 					}
263 				}
264 
265 					// not found (Garbage collected), nothing to do
266 			}
267 		}
268 	}
269 }
270