📄 sharemanagerimpl.java
字号:
/*
* File : ShareManagerImpl.java
* Created : 30-Dec-2003
* By : parg
*
* Azureus - a Java Bittorrent client
*
* 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; either version 2 of the License.
*
* 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 ( see the LICENSE file ).
*
* 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 org.gudy.azureus2.pluginsimpl.local.sharing;
/**
* @author parg
*
*/
import java.io.*;
import java.net.*;
import java.util.*;
import org.gudy.azureus2.plugins.torrent.*;
import org.gudy.azureus2.pluginsimpl.local.torrent.*;
import org.gudy.azureus2.plugins.sharing.*;
import org.gudy.azureus2.core3.util.*;
import org.gudy.azureus2.core3.config.*;
import org.gudy.azureus2.core3.logging.*;
import org.gudy.azureus2.core3.torrent.*;
import org.gudy.azureus2.core3.tracker.host.*;
import org.gudy.azureus2.core3.tracker.util.TRTrackerUtils;
public class
ShareManagerImpl
implements ShareManager, TOTorrentProgressListener, ParameterListener
{
private static final LogIDs LOGID = LogIDs.PLUGIN;
public static final String TORRENT_STORE = "shares";
public static final String TORRENT_SUBSTORE = "cache";
public static final int MAX_FILES_PER_DIR = 1000;
public static final int MAX_DIRS = 1000;
protected static ShareManagerImpl singleton;
private static AEMonitor class_mon = new AEMonitor( "ShareManager:class" );
protected AEMonitor this_mon = new AEMonitor( "ShareManager" );
protected TOTorrentCreator to_creator;
public static ShareManagerImpl
getSingleton()
throws ShareException
{
try{
class_mon.enter();
if ( singleton == null ){
singleton = new ShareManagerImpl();
}
return( singleton );
}finally{
class_mon.exit();
}
}
private volatile boolean initialised;
private volatile boolean initialising;
private File share_dir;
private URL[] announce_urls;
private ShareConfigImpl config;
private Map shares = new HashMap();
private shareScanner current_scanner;
private List listeners = new ArrayList();
protected
ShareManagerImpl()
throws ShareException
{
COConfigurationManager.addListener(
new COConfigurationListener()
{
public void
configurationSaved()
{
announce_urls = null;
}
});
}
public void
initialise()
throws ShareException
{
try{
this_mon.enter();
if ( !initialised ){
try{
initialising = true;
initialised = true;
share_dir = FileUtil.getUserFile( TORRENT_STORE );
FileUtil.mkdirs(share_dir);
config = new ShareConfigImpl();
try{
config.suspendSaving();
config.loadConfig(this);
checkConsistency();
}finally{
Iterator it = shares.values().iterator();
while(it.hasNext()){
ShareResourceImpl resource = (ShareResourceImpl)it.next();
if ( resource.getType() == ShareResource.ST_DIR_CONTENTS ){
for (int i=0;i<listeners.size();i++){
try{
((ShareManagerListener)listeners.get(i)).resourceAdded( resource );
}catch( Throwable e ){
Debug.printStackTrace( e );
}
}
}
}
config.resumeSaving();
}
readAZConfig();
}finally{
initialising = false;
}
}
}finally{
this_mon.exit();
}
}
public boolean
isInitialising()
{
return( initialising );
}
protected void
readAZConfig()
{
COConfigurationManager.addParameterListener( "Sharing Rescan Enable", this );
readAZConfigSupport();
}
public void
parameterChanged(
String name )
{
readAZConfigSupport();
}
protected void
readAZConfigSupport()
{
try{
this_mon.enter();
boolean scan_enabled = COConfigurationManager.getBooleanParameter( "Sharing Rescan Enable" );
if ( !scan_enabled ){
current_scanner = null;
}else if ( current_scanner == null ){
current_scanner = new shareScanner();
}
}finally{
this_mon.exit();
}
}
protected ShareConfigImpl
getShareConfig()
{
return( config );
}
protected void
checkConsistency()
throws ShareException
{
// copy set for iteration as consistency check can delete resource
Iterator it = new HashSet(shares.values()).iterator();
while(it.hasNext()){
ShareResourceImpl resource = (ShareResourceImpl)it.next();
try{
resource.checkConsistency();
}catch( ShareException e ){
Debug.printStackTrace(e);
}
}
}
protected void
deserialiseResource(
Map map )
{
try{
ShareResourceImpl new_resource = null;
int type = ((Long)map.get("type")).intValue();
if ( type == ShareResource.ST_FILE ||
type == ShareResource.ST_DIR ){
new_resource = ShareResourceFileOrDirImpl.deserialiseResource( this, map, type );
}else{
new_resource = ShareResourceDirContentsImpl.deserialiseResource( this, map );
}
if ( new_resource != null ){
ShareResourceImpl old_resource = (ShareResourceImpl)shares.get(new_resource.getName());
if ( old_resource != null ){
old_resource.delete(true);
}
shares.put( new_resource.getName(), new_resource );
// we delay the reporting of dir_contents until all recovery is complete so that
// the resource reported is initialised correctly
if ( type != ShareResource.ST_DIR_CONTENTS ){
for (int i=0;i<listeners.size();i++){
try{
((ShareManagerListener)listeners.get(i)).resourceAdded( new_resource );
}catch( Throwable e ){
Debug.printStackTrace( e );
}
}
}
}
}catch( Throwable e ){
Debug.printStackTrace( e );
}
}
protected String
getNewTorrentLocation()
throws ShareException
{
Random rand = new Random(SystemTime.getCurrentTime());
for (int i=1;i<=MAX_DIRS;i++){
String cache_dir_str = share_dir + File.separator + TORRENT_SUBSTORE + i;
File cache_dir = new File(cache_dir_str);
if ( !cache_dir.exists()){
FileUtil.mkdirs(cache_dir);
}
if ( cache_dir.listFiles().length < MAX_FILES_PER_DIR ){
for (int j=0;j<MAX_FILES_PER_DIR;j++){
long file = Math.abs(rand.nextLong());
File file_name = new File(cache_dir_str + File.separator + file + ".torrent");
if ( !file_name.exists()){
// return path relative to cache_dir to save space
return( TORRENT_SUBSTORE + i + File.separator + file + ".torrent" );
}
}
}
}
throw( new ShareException( "ShareManager: Failed to allocate cache file"));
}
protected void
writeTorrent(
ShareItemImpl item )
throws ShareException
{
try{
item.getTorrent().writeToFile( getTorrentFile(item ));
}catch( TorrentException e ){
throw( new ShareException( "ShareManager: Torrent write fails", e ));
}
}
protected void
readTorrent(
ShareItemImpl item )
throws ShareException
{
try{
TOTorrent torrent = TOTorrentFactory.deserialiseFromBEncodedFile( getTorrentFile(item ));
item.setTorrent(new TorrentImpl(torrent));
}catch( TOTorrentException e ){
throw( new ShareException( "ShareManager: Torrent read fails", e ));
}
}
protected void
deleteTorrent(
ShareItemImpl item )
{
File torrent_file = getTorrentFile(item);
torrent_file.delete();
}
protected boolean
torrentExists(
ShareItemImpl item )
{
return( getTorrentFile(item).exists());
}
protected File
getTorrentFile(
ShareItemImpl item )
{
return( new File(share_dir+File.separator+item.getTorrentLocation()));
}
protected URL[]
getAnnounceURLs()
throws ShareException
{
if ( announce_urls == null ){
String protocol = COConfigurationManager.getStringParameter( "Sharing Protocol" );
if ( protocol.equalsIgnoreCase( "DHT" )){
announce_urls = new URL[]{ TorrentUtils.getDecentralisedEmptyURL()};
}else{
URL[][] tracker_url_sets = TRTrackerUtils.getAnnounceURLs();
if ( tracker_url_sets.length == 0 ){
throw( new ShareException( "ShareManager: Tracker must be configured"));
}
for (int i=0;i<tracker_url_sets.length;i++){
URL[] tracker_urls = tracker_url_sets[i];
if ( tracker_urls[0].getProtocol().equalsIgnoreCase( protocol )){
announce_urls = tracker_urls;
break;
}
}
if ( announce_urls == null ){
throw( new ShareException( "ShareManager: Tracker must be configured for protocol '" + protocol + "'" ));
}
}
}
return( announce_urls );
}
protected boolean
getAddHashes()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -