package com.limegroup.gnutella.archive;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.limegroup.gnutella.FileDesc;
import com.limegroup.gnutella.util.CoWList;
abstract class AbstractContribution implements Contribution {
private String _title;
private String _description;
private int _media;
private int _collection;
private int _type;
private String _username, _password;
private final LinkedHashMap _files = new LinkedHashMap();
/** String -> String */
private HashMap _fields = new HashMap();
private volatile boolean _cancelled;
/** LOCKING: this */
private String _curFileName;
private int _filesSent = 0;
private long _totalBytesSent;
protected long _totalUploadSize;
protected final Map _fileNames2Progress = new HashMap();
private int _id = NOT_CONNECTED;
private final List _uploadListeners = new CoWList(CoWList.ARRAY_LIST);
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#getVerificationUrl()
*/
abstract public String getVerificationUrl();
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#requestIdentifier(java.lang.String)
*/
abstract public String requestIdentifier( String identifier ) throws
IdentifierUnavailableException, IOException;
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#getIdentifier()
*/
abstract public String getIdentifier();
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#upload()
*/
abstract public void upload() throws IOException;
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#addFileDesc(com.limegroup.gnutella.FileDesc)
*/
public void addFileDesc( FileDesc fd ) {
_files.put( fd, new File(fd));
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#removeFileDesc(com.limegroup.gnutella.FileDesc)
*/
public void removeFileDesc( FileDesc fd ) {
_files.remove( fd );
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#containsFileDesc(com.limegroup.gnutella.FileDesc)
*/
public boolean containsFileDesc( FileDesc fd ) {
return _files.containsKey( fd );
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#cancel()
*/
public void cancel() {
_cancelled = true;
}
boolean isCancelled() {
return _cancelled;
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#getFileDescs()
*/
public Set getFileDescs() {
return Collections.unmodifiableSet( _files.keySet() );
}
protected Collection getFiles() {
return Collections.unmodifiableCollection(_files.values());
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#setTitle(java.lang.String)
*/
public void setTitle( String title ) {
_title = title;
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#getTitle()
*/
public String getTitle() {
return _title;
}
public void setDescription( String description )
throws DescriptionTooShortException {
_description = description;
}
public String getDescription() {
return _description;
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#setMedia(int)
*/
public void setMedia( int media ) {
if ( Archives.getMediaString( media ) == null ) {
throw new IllegalArgumentException( "Invalid media type: "
+ media );
}
_media = media;
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#getMedia()
*/
public int getMedia() {
return _media;
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#setCollection(int)
*/
public void setCollection( int collection ) {
if ( Archives.getCollectionString( collection ) == null ) {
throw new IllegalArgumentException( "Invalid collection type: "
+ collection );
}
_collection = collection;
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#getCollection()
*/
public int getCollection() {
return _collection;
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#setType(int)
*/
public void setType( int type ) {
if (Archives.getTypeString( type ) == null ) {
throw new IllegalArgumentException( "Invalid dublin-core type: "
+ type );
}
_type = type;
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#getType()
*/
public int getType() {
return _type;
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#getPassword()
*/
public String getPassword() {
return _password;
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#setPassword(java.lang.String)
*/
public void setPassword(String password) {
_password = password;
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#getUsername()
*/
public String getUsername() {
return _username;
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#setUsername(java.lang.String)
*/
public void setUsername(String username) {
_username = username;
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#setField(java.lang.String, java.lang.String)
*/
public void setField( String field, String value ) {
_fields.put( field, value );
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#getField(java.lang.String)
*/
public String getField( String field ) {
return (String) _fields.get( field );
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#removeField(java.lang.String)
*/
public void removeField( String field ) {
_fields.remove( field );
}
protected Map getFields() {
return Collections.unmodifiableMap( _fields );
}
protected class UploadFileProgress {
private final long _fileSize;
private long _bytesSent = 0;
public UploadFileProgress( long fileSize ) {
_fileSize = fileSize;
}
public long getFileSize() {
return _fileSize;
}
public long getBytesSent() {
return _bytesSent;
}
public void setBytesSent( long bytesSent ) {
_bytesSent = bytesSent;
}
public void incrBytesSent( long bytesSentDelta ) {
_bytesSent += bytesSentDelta;
}
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#addListener(com.limegroup.gnutella.archive.UploadListener)
*/
public void addListener( UploadListener l ) {
_uploadListeners.add( l );
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#removeListener(com.limegroup.gnutella.archive.UploadListener)
*/
public void removeListener( UploadListener l ) {
_uploadListeners.remove( l );
}
private void notifyStateChange() {
for (Iterator i = _uploadListeners.iterator(); i.hasNext();) {
UploadListener l = (UploadListener) i.next();
switch ( _id ) {
case FILE_STARTED:
l.fileStarted();
break;
case FILE_PROGRESSED:
l.fileProgressed();
break;
case FILE_COMPLETED:
l.fileCompleted();
break;
case CONNECTED:
l.connected();
break;
case CHECKIN_STARTED:
l.checkinStarted();
break;
case CHECKIN_COMPLETED:
l.checkinCompleted();
break;
default:
break;
}
}
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#getFilesSent()
*/
public synchronized int getFilesSent() {
return _filesSent;
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#getTotalFiles()
*/
public synchronized int getTotalFiles() {
return _fileNames2Progress.size();
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#getFileBytesSent()
*/
public synchronized long getFileBytesSent() {
return ((UploadFileProgress) _fileNames2Progress.get( _curFileName )).getBytesSent();
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#getFileSize()
*/
public synchronized long getFileSize() {
return ((UploadFileProgress) _fileNames2Progress.get( _curFileName )).getFileSize();
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#getTotalBytesSent()
*/
public synchronized long getTotalBytesSent() {
return _totalBytesSent;
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#getTotalSize()
*/
public synchronized long getTotalSize() {
return _totalUploadSize;
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#getFileName()
*/
public synchronized String getFileName() {
return _curFileName;
}
/* (non-Javadoc)
* @see com.limegroup.gnutella.archive.Contribution#getID()
*/
public int getID() {
return _id;
}
void connected() {
_id = CONNECTED;
}
void fileStarted( String fileName, long bytesSent ) {
_id = FILE_STARTED;
synchronized(this) {
_curFileName = fileName;
((UploadFileProgress) _fileNames2Progress.get( fileName )).setBytesSent( bytesSent );
}
notifyStateChange();
}
void fileStarted( String fileName ) {
fileStarted( fileName, 0 );
}
/**
*
* @param fileName
* @param bytesSent
*
* @throws IllegalStateException
* If fileName does not match the current fileName
*/
void fileProgressed( long bytesSent ) {
_id = FILE_PROGRESSED;
synchronized(this) {
UploadFileProgress progress = (UploadFileProgress) _fileNames2Progress.get( _curFileName );
// find delta
long delta = bytesSent - progress.getBytesSent();
_totalBytesSent += delta;
progress.setBytesSent( bytesSent );
}
notifyStateChange();
}
/**
*
* @param fileName
* @param bytesSentDelta
*
* @throws IllegalStateException
* If fileName does not match the current fileName
*/
void fileProgressedDelta( long bytesSentDelta ) {
_id = FILE_PROGRESSED;
synchronized(this) {
_totalBytesSent += bytesSentDelta;
((UploadFileProgress) _fileNames2Progress.get( _curFileName )).incrBytesSent( bytesSentDelta );
}
notifyStateChange();
}
/**
*
* @param fileName
*
* @throws IllegalStateException
* If fileName does not match the current fileName
*/
void fileCompleted() {
_id = FILE_COMPLETED;
synchronized(this) {
UploadFileProgress progress = (UploadFileProgress) _fileNames2Progress.get( _curFileName );
progress.setBytesSent( progress.getFileSize() );
_filesSent++;
}
notifyStateChange();
}
void checkinStarted() {
_id = CHECKIN_STARTED;
notifyStateChange();
}
void checkinCompleted() {
_id = CHECKIN_COMPLETED;
notifyStateChange();
}
}