/* * Created on Jul 16, 2008 * Created by Paul Gardner * * Copyright 2008 Vuze, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License only. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ package com.aelitis.azureus.core.lws; import java.io.File; import java.net.URL; import java.util.*; import org.gudy.azureus2.core3.logging.LogEvent; import org.gudy.azureus2.core3.logging.LogIDs; import org.gudy.azureus2.core3.logging.Logger; import org.gudy.azureus2.core3.util.AESemaphore; import org.gudy.azureus2.core3.util.AEThread2; import org.gudy.azureus2.core3.util.ByteFormatter; import org.gudy.azureus2.core3.util.Debug; import org.gudy.azureus2.core3.util.HashWrapper; import org.gudy.azureus2.core3.util.SimpleTimer; import org.gudy.azureus2.core3.util.TimerEvent; import org.gudy.azureus2.core3.util.TimerEventPerformer; import org.gudy.azureus2.core3.util.TimerEventPeriodic; import org.gudy.azureus2.core3.util.TorrentUtils; import org.gudy.azureus2.core3.util.UrlUtils; import org.gudy.azureus2.plugins.PluginInterface; import org.gudy.azureus2.plugins.download.Download; import org.gudy.azureus2.pluginsimpl.local.ddb.DDBaseImpl; import org.gudy.azureus2.pluginsimpl.local.ddb.DDBaseTTTorrent; import com.aelitis.azureus.core.AzureusCore; import com.aelitis.azureus.core.AzureusCoreRunningListener; import com.aelitis.azureus.core.AzureusCoreFactory; import com.aelitis.azureus.core.AzureusCoreLifecycleAdapter; import com.aelitis.azureus.plugins.tracker.dht.DHTTrackerPlugin; public class LightWeightSeedManager { private static LightWeightSeedManager singleton = new LightWeightSeedManager(); public static LightWeightSeedManager getSingleton() { return( singleton ); } private Map lws_map = new HashMap(); private boolean started; private Set dht_add_queue = new HashSet(); private boolean borked; private DHTTrackerPlugin dht_tracker_plugin; private DDBaseTTTorrent tttorrent; private TimerEventPeriodic timer; private AESemaphore init_sem = new AESemaphore( "LWSM" ); protected LightWeightSeedManager() { AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() { public void azureusCoreRunning(AzureusCore core) { startUp(); } }); } protected void startUp() { synchronized( this ){ if ( started ){ return; } started = true; } boolean release_now = true; try{ PluginInterface pi = AzureusCoreFactory.getSingleton().getPluginManager().getPluginInterfaceByClass( DHTTrackerPlugin.class ); if ( pi != null ){ final DHTTrackerPlugin plugin = (DHTTrackerPlugin)pi.getPlugin(); new AEThread2( "LWS:waitForPlug", true ) { public void run() { try{ plugin.waitUntilInitialised(); if ( plugin.isRunning()){ tttorrent = DDBaseImpl.getSingleton(AzureusCoreFactory.getSingleton()).getTTTorrent(); } Set to_add; synchronized( this ){ dht_tracker_plugin = plugin; to_add = new HashSet( dht_add_queue ); dht_add_queue.clear(); } Iterator it = to_add.iterator(); while( it.hasNext()){ addDownload( (Download)it.next()); } }finally{ init_sem.releaseForever(); } } }.start(); release_now = false; }else{ synchronized( dht_add_queue ){ borked = true; dht_add_queue.clear(); } } }finally{ if ( release_now ){ init_sem.releaseForever(); } } } public LightWeightSeed add( String name, HashWrapper hash, URL url, File data_location, LightWeightSeedAdapter adapter ) throws Exception { if ( !TorrentUtils.isDecentralised( url )){ throw( new Exception( "Only decentralised torrents supported" )); } LightWeightSeed lws; synchronized( this ){ if ( lws_map.containsKey( hash )){ throw( new Exception( "Seed for hash '" + ByteFormatter.encodeString( hash.getBytes()) + "' already added" )); } lws = new LightWeightSeed( this, name, hash, url, data_location, adapter ); lws_map.put( hash, lws ); if ( timer == null ){ timer = SimpleTimer.addPeriodicEvent( "LWSManager:timer", 60*1000, new TimerEventPerformer() { public void perform( TimerEvent event ) { processTimer(); } }); } log( "Added LWS: " + name + ", " + UrlUtils.getMagnetURI( hash.getBytes())); } lws.start(); return( lws ); } public LightWeightSeed get( HashWrapper hw ) { synchronized( this ){ return((LightWeightSeed)lws_map.get( hw )); } } protected void processTimer() { List to_process; synchronized( this ){ to_process = new ArrayList( lws_map.values()); } for ( int i=0;i<to_process.size();i++){ try{ ((LightWeightSeed)to_process.get(i)).checkDeactivation(); }catch( Throwable e ){ Debug.printStackTrace(e); } } } protected void remove( LightWeightSeed lws ) { lws.stop(); synchronized( this ){ lws_map.remove( lws.getHash()); if ( lws_map.size() == 0 ){ if ( timer != null ){ timer.cancel(); timer = null; } } } log( "Added LWS: " + lws.getName() + ", " + UrlUtils.getMagnetURI( lws.getHash().getBytes())); } protected void addToDHTTracker( Download download ) { synchronized( dht_add_queue ){ if ( borked ){ return; } if ( dht_tracker_plugin == null ){ dht_add_queue.add( download ); return; } } init_sem.reserve(); addDownload( download ); } protected void removeFromDHTTracker( Download download ) { synchronized( dht_add_queue ){ if ( borked ){ return; } if ( dht_tracker_plugin == null ){ dht_add_queue.remove( download ); return; } } init_sem.reserve(); removeDownload( download ); } protected void addDownload( Download download ) { dht_tracker_plugin.addDownload( download ); if ( tttorrent != null ){ tttorrent.addDownload( download ); } } protected void removeDownload( Download download ) { dht_tracker_plugin.removeDownload( download ); if ( tttorrent != null ){ tttorrent.removeDownload( download ); } } protected void log( String str ) { Logger.log(new LogEvent(LogIDs.CORE, str )); } protected void log( String str, Throwable e ) { Logger.log(new LogEvent(LogIDs.CORE, str, e )); } }