/*
* File : TorrentImpl.java
* Created : 08-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.torrent;
import java.net.*;
/**
* @author parg
*
*/
import java.util.Map;
import java.io.File;
import org.gudy.azureus2.core3.download.DownloadManagerState;
import org.gudy.azureus2.core3.download.DownloadManagerStateFactory;
import org.gudy.azureus2.core3.internat.*;
import org.gudy.azureus2.core3.logging.LogRelation;
import org.gudy.azureus2.core3.torrent.*;
import org.gudy.azureus2.core3.util.*;
import org.gudy.azureus2.plugins.PluginInterface;
import org.gudy.azureus2.plugins.torrent.*;
import org.gudy.azureus2.plugins.download.*;
import org.gudy.azureus2.pluginsimpl.local.download.*;
import org.gudy.azureus2.pluginsimpl.local.utils.UtilitiesImpl;
import com.aelitis.azureus.core.AzureusCoreFactory;
import com.aelitis.azureus.plugins.magnet.MagnetPlugin;
public class
TorrentImpl
extends LogRelation
implements Torrent
{
private static MagnetPlugin magnet_plugin;
private PluginInterface pi;
private TOTorrent torrent;
private LocaleUtilDecoder decoder;
private boolean complete;
public
TorrentImpl(
TOTorrent _torrent )
{
this( null, _torrent );
}
public
TorrentImpl(
PluginInterface _pi,
TOTorrent _torrent )
{
pi = _pi;
torrent = _torrent;
}
public String
getName()
{
String utf8Name = torrent.getUTF8Name();
String name = utf8Name == null ? decode( torrent.getName()) : utf8Name;
name = FileUtil.convertOSSpecificChars( name, false );
return( name );
}
public URL
getAnnounceURL()
{
return( torrent.getAnnounceURL());
}
public void
setAnnounceURL(
URL url )
{
torrent.setAnnounceURL( url );
updated();
}
public TorrentAnnounceURLList
getAnnounceURLList()
{
return( new TorrentAnnounceURLListImpl( this ));
}
public TOTorrent
getTorrent()
{
return( torrent );
}
public boolean
isDecentralised()
{
return( TorrentUtils.isDecentralised( torrent ));
}
public boolean
isDecentralisedBackupEnabled()
{
return( TorrentUtils.getDHTBackupEnabled( torrent ));
}
public void
setDecentralisedBackupRequested(
boolean requested )
{
TorrentUtils.setDHTBackupRequested( torrent, requested );
}
public boolean
isDecentralisedBackupRequested()
{
return( TorrentUtils.isDHTBackupRequested( torrent ));
}
public boolean
isPrivate()
{
return( TorrentUtils.getPrivate( torrent ));
}
public void
setPrivate(
boolean priv )
{
TorrentUtils.setPrivate( torrent, priv );
}
public boolean
wasCreatedByUs()
{
return( TorrentUtils.isCreatedTorrent( torrent ));
}
public URL
getMagnetURI()
throws TorrentException
{
if ( magnet_plugin == null ){
PluginInterface magnet_pi = AzureusCoreFactory.getSingleton().getPluginManager().getPluginInterfaceByClass( MagnetPlugin.class );
if ( magnet_pi != null ){
magnet_plugin = (MagnetPlugin)magnet_pi.getPlugin();
}
}
if ( magnet_plugin == null ){
throw( new TorrentException( "MegnetPlugin unavailable" ));
}
try{
URL res = magnet_plugin.getMagnetURL( torrent.getHash());
return( res );
}catch( TOTorrentException e ){
throw( new TorrentException(e ));
}
}
public byte[]
getHash()
{
try{
return( torrent.getHash());
}catch( TOTorrentException e ){
Debug.printStackTrace( e );
return( null );
}
}
public long
getSize()
{
return( torrent.getSize());
}
public String
getComment()
{
return( decode(torrent.getComment()));
}
public void
setComment(
String comment )
{
torrent.setComment( comment );
}
public long
getCreationDate()
{
return( torrent.getCreationDate());
}
public String
getCreatedBy()
{
return( decode( torrent.getCreatedBy()));
}
public long
getPieceSize()
{
return( torrent.getPieceLength());
}
public long
getPieceCount()
{
return( torrent.getNumberOfPieces());
}
public byte[][]
getPieces()
{
try{
return( torrent.getPieces());
}catch( TOTorrentException e ){
Debug.printStackTrace( e );
return( new byte[0][0] );
}
}
public TorrentFile[]
getFiles()
{
TOTorrentFile[] files = torrent.getFiles();
TorrentFile[] res = new TorrentFile[files.length];
for (int i=0;i<res.length;i++){
TOTorrentFile tf = files[i];
byte[][] comps = tf.getPathComponents();
String name = "";
for (int j=0;j<comps.length;j++){
String comp = decode(comps[j]);
comp = FileUtil.convertOSSpecificChars( comp, j != comps.length-1 );
name += (j==0?"":File.separator)+comp;
}
res[i] = new TorrentFileImpl(name, tf.getLength());
}
return( res );
}
protected void
getDecoder()
{
// We defer the getting of the decoder until it is required as this Torrent may have been
// created in order to simply remove additional properties from it before serialising it
// Indeed, this was happening and unfortunately resulting in 1) the encoding being
// serialised 2) the user being prompted for an encoding choice
try{
decoder = LocaleTorrentUtil.getTorrentEncoding( torrent );
}catch( Throwable e ){
}
}
public String
getEncoding()
{
getDecoder();
if ( decoder != null ){
return( decoder.getName());
}
return( Constants.DEFAULT_ENCODING );
}
public void
setEncoding(String encoding)throws TorrentEncodingException {
try {
LocaleTorrentUtil.setTorrentEncoding(torrent, encoding);
} catch(LocaleUtilEncodingException e) {
throw new TorrentEncodingException("Failed to set the encoding",e);
}
}
public void
setDefaultEncoding() throws TorrentEncodingException {
setEncoding(Constants.DEFAULT_ENCODING);
}
protected String
decode(
byte[] data )
{
getDecoder();
if ( data != null ){
if ( decoder != null ){
try{
return( decoder.decodeString(data));
}catch( Throwable e ){
}
}
return( new String(data));
}
return( "" );
}
public Object
getAdditionalProperty(
String name )
{
return( torrent.getAdditionalProperty( name ));
}
public Torrent
removeAdditionalProperties()
{
try{
TOTorrent t = TOTorrentFactory.deserialiseFromMap(torrent.serialiseToMap());
t.removeAdditionalProperties();
return( new TorrentImpl( t ));
}catch( TOTorrentException e ){
Debug.printStackTrace(e);
return( this );
}
}
public void
setPluginStringProperty(
String name,
String value )
{
PluginInterface p = pi;
if ( p == null ){
p = UtilitiesImpl.getPluginThreadContext();
}
if ( p == null ){
name = "<internal>." + name;
}else{
name = p.getPluginID() + "." + name;
}
TorrentUtils.setPluginStringProperty( torrent, name, value );
}
public String
getPluginStringProperty(
String name )
{
PluginInterface p = pi;
if ( p == null ){
p = UtilitiesImpl.getPluginThreadContext();
}
if ( p == null ){
name = "<internal>." + name;
}else{
name = p.getPluginID() + "." + name;
}
return( TorrentUtils.getPluginStringProperty( torrent, name ));
}
public void
setMapProperty(
String name,
Map value )
{
TorrentUtils.setPluginMapProperty( torrent, name, value );
}
public Map
getMapProperty(
String name )
{
return( TorrentUtils.getPluginMapProperty( torrent, name ));
}
public Map
writeToMap()
throws TorrentException
{
try{
return( torrent.serialiseToMap());
}catch( TOTorrentException e ){
throw( new TorrentException( "Torrent::writeToMap: fails", e ));
}
}
public byte[]
writeToBEncodedData()
throws TorrentException
{
try{
Map map = torrent.serialiseToMap();
return( BEncoder.encode( map ));
}catch( Throwable e ){
throw( new TorrentException( "Torrent::writeToBEncodedData: fails", e ));
}
}
public void
writeToFile(
File file )
throws TorrentException
{
try{
// don't use TorrentUtils.writeToFile as this updates the internal torrent
// file reference an means that the torrent get's auto-written to the new
// location in future, most likley NOT the desired behaviour
torrent.serialiseToBEncodedFile( file );
}catch( TOTorrentException e ){
throw( new TorrentException( "Torrent::writeToFile: fails", e ));
}
}
protected void
updated()
{
try{
DownloadImpl dm = (DownloadImpl)DownloadManagerImpl.getDownloadStatic( torrent );
if ( dm != null ){
dm.torrentChanged();
}
}catch( DownloadException e ){
// torrent may not be running
}
}
public void
save()
throws TorrentException
{
try{
TorrentUtils.writeToFile( torrent );
}catch( TOTorrentException e ){
throw( new TorrentException( "Torrent::save Fails", e ));
}
}
public void
setComplete(
File data_dir )
throws TorrentException
{
try{
LocaleTorrentUtil.setDefaultTorrentEncoding( torrent );
DownloadManagerState download_manager_state =
DownloadManagerStateFactory.getDownloadState( torrent );
TorrentUtils.setResumeDataCompletelyValid( download_manager_state );
download_manager_state.save();
complete = true;
}catch( Throwable e ){
throw( new TorrentException("encoding selection fails", e ));
}
}
public boolean
isComplete()
{
// TODO: could check the download state too I guess...
return( complete );
}
// Pass LogRelation off to core objects
/* (non-Javadoc)
* @see org.gudy.azureus2.core3.logging.LogRelation#getLogRelationText()
*/
public String getRelationText() {
return propogatedRelationText(torrent);
}
/* (non-Javadoc)
* @see org.gudy.azureus2.core3.logging.LogRelation#getQueryableInterfaces()
*/
public Object[] getQueryableInterfaces() {
return new Object[] { torrent };
}
public boolean isSimpleTorrent() {return torrent.isSimpleTorrent();}
}