1 /*
2  * File    : TrackerImpl.java
3  * Created : 08-Dec-2003
4  * By      : parg
5  *
6  * Azureus - a Java Bittorrent client
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details ( see the LICENSE file ).
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22 
23 package org.gudy.azureus2.pluginsimpl.local.tracker;
24 
25 /**
26  * @author parg
27  *
28  */
29 
30 import java.net.InetAddress;
31 import java.net.URL;
32 import java.util.*;
33 
34 import org.gudy.azureus2.plugins.tracker.*;
35 import org.gudy.azureus2.plugins.tracker.web.*;
36 import org.gudy.azureus2.plugins.torrent.*;
37 import org.gudy.azureus2.pluginsimpl.local.torrent.*;
38 import org.gudy.azureus2.core3.tracker.host.*;
39 import org.gudy.azureus2.core3.tracker.util.TRTrackerUtils;
40 import org.gudy.azureus2.core3.util.AEMonitor;
41 import org.gudy.azureus2.core3.util.Debug;
42 
43 public class
44 TrackerImpl
45 	extends		TrackerWCHelper
46 	implements 	Tracker, TRHostListener2, TRHostAuthenticationListener
47 {
48 	private static TrackerImpl	singleton;
49 	private static AEMonitor 		class_mon 	= new AEMonitor( "Tracker" );
50 
51 	private List	listeners	= new ArrayList();
52 
53 	private TRHost		host;
54 
55 	private List<TrackerAuthenticationListener>	auth_listeners	= new ArrayList<TrackerAuthenticationListener>();
56 
57 
58 	public static Tracker
getSingleton()59 	getSingleton()
60 	{
61 		try{
62 			class_mon.enter();
63 
64 			if ( singleton == null ){
65 
66 				singleton	= new TrackerImpl( TRHostFactory.getSingleton());
67 			}
68 
69 			return( singleton );
70 
71 		}finally{
72 
73 			class_mon.exit();
74 		}
75 	}
76 
77 	protected
TrackerImpl( TRHost _host )78 	TrackerImpl(
79 		TRHost		_host )
80 	{
81 		setTracker( this );
82 
83 		host		= _host;
84 
85 		host.addListener2( this );
86 	}
87 
88 	public String
getName()89 	getName()
90 	{
91 		return( host.getName());
92 	}
93 
94 	public void
setEnableKeepAlive( boolean enable )95 	setEnableKeepAlive(
96 		boolean		enable )
97 	{
98 		Debug.out( "Keep alive setting ignored for tracker" );
99 	}
100 
101 	public URL[]
getURLs()102 	getURLs()
103 	{
104 		URL[][]	url_sets = TRTrackerUtils.getAnnounceURLs();
105 
106 		URL[]	res = new URL[url_sets.length];
107 
108 		for (int i=0;i<res.length;i++){
109 
110 			res[i] = url_sets[i][0];
111 		}
112 
113 		return( res );
114 	}
115 
116 	public InetAddress
getBindIP()117 	getBindIP()
118 	{
119 		return( host.getBindIP());
120 	}
121 
122 	public TrackerTorrent
host( Torrent _torrent, boolean _persistent )123 	host(
124 		Torrent		_torrent,
125 		boolean		_persistent )
126 
127 		throws TrackerException
128 	{
129 		return( host( _torrent, _persistent, false ));
130 	}
131 
132 	public TrackerTorrent
host( Torrent _torrent, boolean _persistent, boolean _passive )133 	host(
134 		Torrent		_torrent,
135 		boolean		_persistent,
136 		boolean		_passive )
137 
138 		throws TrackerException
139 	{
140 		TorrentImpl	torrent = (TorrentImpl)_torrent;
141 
142 		try{
143 			return( new TrackerTorrentImpl( host.hostTorrent( torrent.getTorrent(), _persistent, _passive )));
144 
145 		}catch( Throwable e ){
146 
147 			throw( new TrackerException( "Tracker: host operation fails", e ));
148 		}
149 	}
150 
151 	public TrackerTorrent
publish( Torrent _torrent)152 	publish(
153 			Torrent _torrent)
154 
155 		throws TrackerException
156 	{
157 		TorrentImpl	torrent = (TorrentImpl)_torrent;
158 
159 		try{
160 			return( new TrackerTorrentImpl( host.publishTorrent( torrent.getTorrent() )));
161 
162 		}catch( Throwable e ){
163 
164 			throw( new TrackerException( "Tracker: publish operation fails", e ));
165 		}
166 	}
167 
168 	public TrackerTorrent[]
getTorrents()169 	getTorrents()
170 	{
171 		TRHostTorrent[]	hts = host.getTorrents();
172 
173 		TrackerTorrent[]	res = new TrackerTorrent[hts.length];
174 
175 		for (int i=0;i<hts.length;i++){
176 
177 			res[i] = new TrackerTorrentImpl(hts[i]);
178 		}
179 
180 		return( res );
181 	}
182 
183 	public TrackerTorrent
getTorrent( Torrent torrent )184 	getTorrent(
185 		Torrent		torrent )
186 	{
187 		TRHostTorrent	ht = host.getHostTorrent(((TorrentImpl)torrent).getTorrent());
188 
189 		if ( ht == null ){
190 
191 			return( null );
192 		}
193 
194 		return( new TrackerTorrentImpl( ht ));
195 	}
196 
197 	public TrackerWebContext
createWebContext( int port, int protocol )198 	createWebContext(
199 		int		port,
200 		int		protocol )
201 
202 		throws TrackerException
203 	{
204 		return( new TrackerWebContextImpl( this, null, port, protocol, null, null ));
205 	}
206 
207 	public TrackerWebContext
createWebContext( String name, int port, int protocol )208 	createWebContext(
209 		String	name,
210 		int		port,
211 		int		protocol )
212 
213 		throws TrackerException
214 	{
215 		return( new TrackerWebContextImpl( this, name, port, protocol, null, null ));
216 	}
217 
218 	public TrackerWebContext
createWebContext( String name, int port, int protocol, InetAddress bind_ip )219     createWebContext(
220     	String		name,
221     	int			port,
222 		int			protocol,
223 		InetAddress	bind_ip )
224 
225     	throws TrackerException
226     {
227 		return( new TrackerWebContextImpl( this, name, port, protocol, bind_ip, null ));
228     }
229 
230 	public TrackerWebContext
createWebContext( String name, int port, int protocol, InetAddress bind_ip, Map<String,Object> properties )231     createWebContext(
232     	String					name,
233     	int						port,
234 		int						protocol,
235 		InetAddress				bind_ip,
236 		Map<String,Object>		properties )
237 
238     	throws TrackerException
239     {
240 		return( new TrackerWebContextImpl( this, name, port, protocol, bind_ip, properties ));
241     }
242 
243 	public void
torrentAdded( TRHostTorrent t )244 	torrentAdded(
245 		TRHostTorrent		t )
246 	{
247 		try{
248 			this_mon.enter();
249 
250 			for (int i=0;i<listeners.size();i++){
251 
252 				((TrackerListener)listeners.get(i)).torrentAdded(new TrackerTorrentImpl(t));
253 			}
254 		}finally{
255 
256 			this_mon.exit();
257 		}
258 	}
259 
260 	public void
torrentChanged( TRHostTorrent t )261 	torrentChanged(
262 		TRHostTorrent		t )
263 	{
264 		for (int i=0;i<listeners.size();i++){
265 
266 			((TrackerListener)listeners.get(i)).torrentChanged(new TrackerTorrentImpl(t));
267 		}
268 	}
269 
270 
271 	public void
torrentRemoved( TRHostTorrent t )272 	torrentRemoved(
273 		TRHostTorrent		t )
274 	{
275 		try{
276 			this_mon.enter();
277 
278 			for (int i=0;i<listeners.size();i++){
279 
280 				((TrackerListener)listeners.get(i)).torrentRemoved(new TrackerTorrentImpl(t));
281 			}
282 		}finally{
283 
284 			this_mon.exit();
285 		}
286 	}
287 
288 
289 	public void
addListener( TrackerListener listener )290 	addListener(
291 		TrackerListener		listener )
292 	{
293 		try{
294 			this_mon.enter();
295 
296 			listeners.add( listener );
297 
298 			TrackerTorrent[] torrents = getTorrents();
299 
300 			for (int i=0;i<torrents.length;i++){
301 
302 				listener.torrentAdded( torrents[i]);
303 			}
304 		}finally{
305 
306 			this_mon.exit();
307 		}
308 	}
309 
310 	public void
removeListener( TrackerListener listener )311 	removeListener(
312 		TrackerListener		listener )
313 	{
314 		try{
315 			this_mon.enter();
316 
317 			listeners.remove( listener );
318 
319 		}finally{
320 
321 			this_mon.exit();
322 		}
323 	}
324 
325 	public boolean
authenticate( String headers, URL resource, String user, String password )326 	authenticate(
327 		String		headers,
328 		URL			resource,
329 		String		user,
330 		String		password )
331 	{
332 		for (int i=0;i<auth_listeners.size();i++){
333 
334 			try{
335 				TrackerAuthenticationListener listener = auth_listeners.get(i);
336 
337 				boolean res;
338 
339 				if ( listener instanceof TrackerAuthenticationAdapter ){
340 
341 					res = ((TrackerAuthenticationAdapter)listener).authenticate( headers, resource, user, password );
342 
343 				}else{
344 
345 					res = listener.authenticate( resource, user, password );
346 				}
347 
348 				if ( res ){
349 
350 					return(true );
351 				}
352 			}catch( Throwable e ){
353 
354 				Debug.printStackTrace( e );
355 			}
356 		}
357 
358 		return( false );
359 	}
360 
361 	public byte[]
authenticate( URL resource, String user )362 	authenticate(
363 		URL			resource,
364 		String		user )
365 	{
366 		for (int i=0;i<auth_listeners.size();i++){
367 
368 			try{
369 				byte[] res = ((TrackerAuthenticationListener)auth_listeners.get(i)).authenticate( resource, user );
370 
371 				if ( res != null ){
372 
373 					return( res );
374 				}
375 			}catch( Throwable e ){
376 
377 				Debug.printStackTrace( e );
378 			}
379 		}
380 
381 		return( null );
382 	}
383 
384 	public void
addAuthenticationListener( TrackerAuthenticationListener l )385 	addAuthenticationListener(
386 		TrackerAuthenticationListener	l )
387 	{
388 		try{
389 			this_mon.enter();
390 
391 			auth_listeners.add(l);
392 
393 			if ( auth_listeners.size() == 1 ){
394 
395 				host.addAuthenticationListener( this );
396 			}
397 		}finally{
398 
399 			this_mon.exit();
400 		}
401 	}
402 
403 	public void
removeAuthenticationListener( TrackerAuthenticationListener l )404 	removeAuthenticationListener(
405 		TrackerAuthenticationListener	l )
406 	{
407 		try{
408 			this_mon.enter();
409 
410 			auth_listeners.remove(l);
411 
412 			if ( auth_listeners.size() == 0 ){
413 
414 				host.removeAuthenticationListener( this );
415 			}
416 		}finally{
417 
418 			this_mon.exit();
419 		}
420 	}
421 
422 	public void
destroy()423 	destroy()
424 	{
425 		super.destroy();
426 
427 		auth_listeners.clear();
428 
429 		host.removeAuthenticationListener( this );
430 
431 		listeners.clear();
432 
433 		host.close();
434 	}
435 }
436