diff --git a/lib/installer-exclude/joscar-client.jar b/lib/installer-exclude/joscar-client.jar index 4c0df6266..f548254df 100644 Binary files a/lib/installer-exclude/joscar-client.jar and b/lib/installer-exclude/joscar-client.jar differ diff --git a/lib/installer-exclude/joscar-protocol.jar b/lib/installer-exclude/joscar-protocol.jar index 5ded8ba2c..0df80bf07 100644 Binary files a/lib/installer-exclude/joscar-protocol.jar and b/lib/installer-exclude/joscar-protocol.jar differ diff --git a/src/net/java/sip/communicator/impl/filehistory/FileHistoryServiceImpl.java b/src/net/java/sip/communicator/impl/filehistory/FileHistoryServiceImpl.java index 57d7ad248..7e2c9937b 100644 --- a/src/net/java/sip/communicator/impl/filehistory/FileHistoryServiceImpl.java +++ b/src/net/java/sip/communicator/impl/filehistory/FileHistoryServiceImpl.java @@ -752,7 +752,7 @@ public void fileTransferRequestReceived(FileTransferRequestEvent event) historyWriter.addRecord(new String[]{ req.getFileName(), - getDirection(FileTransfer.IN), + getDirection(FileTransfer.IN), String.valueOf(event.getTimestamp().getTime()), FILE_TRANSFER_ACTIVE, req.getID() @@ -835,6 +835,24 @@ public void fileTransferRequestRejected(FileTransferRequestEvent event) public void fileTransferRequestCanceled(FileTransferRequestEvent event) { + try + { + IncomingFileTransferRequest req = event.getRequest(); + + History history = getHistory(null, req.getSender()); + HistoryWriter historyWriter = history.getWriter(); + + historyWriter.updateRecord( + STRUCTURE_NAMES[4], + req.getID(), + STRUCTURE_NAMES[3], + FileRecord.CANCELED + ); + } + catch (IOException e) + { + logger.error("Could not add file transfer log to history", e); + } } /** diff --git a/src/net/java/sip/communicator/impl/protocol/icq/FileTransferImpl.java b/src/net/java/sip/communicator/impl/protocol/icq/FileTransferImpl.java new file mode 100644 index 000000000..28271e366 --- /dev/null +++ b/src/net/java/sip/communicator/impl/protocol/icq/FileTransferImpl.java @@ -0,0 +1,241 @@ +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.impl.protocol.icq; + +import java.io.*; + +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.service.protocol.event.*; +import net.java.sip.communicator.util.*; +import net.kano.joustsim.oscar.oscar.service.icbm.ft.*; +import net.kano.joustsim.oscar.oscar.service.icbm.ft.FileTransfer; +import net.kano.joustsim.oscar.oscar.service.icbm.ft.controllers.*; +import net.kano.joustsim.oscar.oscar.service.icbm.ft.events.*; +import net.kano.joustsim.oscar.oscar.service.icbm.ft.state.*; + +/** + * The Filetransfer imeplementation for icq. + * @author Damian Minkov + */ +public class FileTransferImpl + extends AbstractFileTransfer +{ + /** + * Logger + */ + private static final Logger logger = + Logger.getLogger(FileTransferImpl.class); + + private String id = null; + private Contact contact = null; + private File file = null; + private int direction = -1; + private long transferedBytes; + private FileTransfer fileTransfer; + + public FileTransferImpl( + FileTransfer fileTransfer, + String id, Contact contact, File file, int direction) + { + this.fileTransfer = fileTransfer; + this.id = id; + this.contact = contact; + this.file = file; + this.direction = direction; + + fileTransfer.addEventListener(new IcqFileTransferEventListener()); + } + + /** + * Cancels this file transfer. When this method is called transfer should + * be interrupted. + */ + public void cancel() + { + fileTransfer.close(); + } + + /** + * Returns the number of bytes already transfered through this file transfer. + * + * @return the number of bytes already transfered through this file transfer + */ + public long getTransferedBytes() + { + return transferedBytes; + } + + /** + * Uniquie ID that is identifying the FileTransfer + * if the request has been accepted. + * + * @return the id. + */ + public String getID() + { + return id; + } + + /** + * The file transfer direction. + * @return returns the direction of the file transfer : IN or OUT. + */ + public int getDirection() + { + return direction; + } + + /** + * Returns the file that is transfered. + * + * @return the file + */ + public File getFile() + { + return file; + } + + /** + * Returns the contact that we are transfering files with. + * @return the contact. + */ + public Contact getContact() + { + return contact; + } + + /** + * @param transferedBytes the transferedBytes to set + */ + public void setTransferedBytes(long transferedBytes) + { + this.transferedBytes = transferedBytes; + } + + /** + * Provides support for files sent and received. + */ + class IcqFileTransferEventListener + implements RvConnectionEventListener + { + public void handleEventWithStateChange( + final RvConnection transfer, + RvConnectionState state, + RvConnectionEvent event) + { + if (state==FileTransferState.CONNECTING) + { + // this both are hacks that detects cancels while transfering + // as only connection is closed from other side + // we detect it by receiving ConnectionTimedOutEvent + if(transfer instanceof IncomingFileTransferImpl) + { + ((IncomingFileTransferImpl)transfer).getStateController(). + addControllerListener(new ControllerListener() + { + + public void handleControllerSucceeded( + StateController controller, SuccessfulStateInfo info) + { + } + + public void handleControllerFailed( + StateController controller, FailedStateInfo info) + { + if(info instanceof FailureEventInfo + && ((FailureEventInfo)info).getEvent() + instanceof ConnectionTimedOutEvent) + { + FileTransferImpl.this.fireStatusChangeEvent( + FileTransferStatusChangeEvent.CANCELED); + fileTransfer.close(); + } + } + }); + } + else if(transfer instanceof OutgoingFileTransferImpl) + { + ((OutgoingFileTransferImpl)transfer).getStateController(). + addControllerListener(new ControllerListener() + { + + public void handleControllerSucceeded( + StateController controller, SuccessfulStateInfo info) + { + } + + public void handleControllerFailed( + StateController controller, FailedStateInfo info) + { + if(info instanceof FailureEventInfo + && ((FailureEventInfo)info).getEvent() + instanceof ConnectionTimedOutEvent) + { + FileTransferImpl.this.fireStatusChangeEvent( + FileTransferStatusChangeEvent.CANCELED); + fileTransfer.close(); + } + } + }); + } + } + else if (state==FileTransferState.FINISHED) + { + fireStatusChangeEvent(FileTransferStatusChangeEvent.COMPLETED); + } + else if (state==FileTransferState.FAILED) + { + if(event instanceof LocallyCancelledEvent) + { + // sender cancels before other party accepts + fireStatusChangeEvent(FileTransferStatusChangeEvent.CANCELED); + } + else if(event instanceof BuddyCancelledEvent) + { + fireStatusChangeEvent(FileTransferStatusChangeEvent.REFUSED); + } + else + fireStatusChangeEvent(FileTransferStatusChangeEvent.FAILED); + } + else if (state==FileTransferState.TRANSFERRING) + { + if (event instanceof TransferringFileEvent) + { + fireStatusChangeEvent( + FileTransferStatusChangeEvent.IN_PROGRESS); + + final ProgressStatusProvider psp = ( + (TransferringFileEvent)event).getProgressProvider(); + + new Thread("Transfer for " + transfer.getBuddyScreenname()) + { + public void run() + { + while (transfer.isOpen()) + { + long transfered = psp.getPosition(); + + setTransferedBytes(transfered); + fireProgressChangeEvent( + System.currentTimeMillis(), (int)transfered); + + try { + Thread.sleep(100); + } + catch (InterruptedException e) + {} + } + } + }.start(); + } + } + } + public void handleEvent(RvConnection transfer, RvConnectionEvent event) + { + } + } +} diff --git a/src/net/java/sip/communicator/impl/protocol/icq/IncomingFileTransferRequestIcqImpl.java b/src/net/java/sip/communicator/impl/protocol/icq/IncomingFileTransferRequestIcqImpl.java new file mode 100644 index 000000000..bec359e0c --- /dev/null +++ b/src/net/java/sip/communicator/impl/protocol/icq/IncomingFileTransferRequestIcqImpl.java @@ -0,0 +1,216 @@ +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.impl.protocol.icq; + +import java.io.File; +import java.util.*; + +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.service.protocol.FileTransfer; +import net.java.sip.communicator.service.protocol.event.*; +import net.java.sip.communicator.util.*; + +import net.kano.joscar.rvcmd.*; +import net.kano.joustsim.oscar.oscar.service.icbm.ft.*; + + +/** + * Icq implementation of the incoming file transfer request + * + * @author Nicolas Riegel + * @author Damian Minkov + */ +public class IncomingFileTransferRequestIcqImpl + implements IncomingFileTransferRequest +{ + /** + * Logger + */ + private static final Logger logger = + Logger.getLogger(IncomingFileTransferRequestIcqImpl.class); + + /** + * The icq provider. + */ + private ProtocolProviderServiceIcqImpl icqProvider; + + private OperationSetFileTransferIcqImpl fileTransferOpSet; + + /** + * The icq file transfer request received + */ + private IncomingFileTransfer incomingFileTransfer = null; + + private Contact sender = null; + + private Date date; + + private String id; + + /** + * Constructor + * + * @param fileTransfer icq file transfer request that was received + */ + public IncomingFileTransferRequestIcqImpl( + ProtocolProviderServiceIcqImpl icqProvider, + OperationSetFileTransferIcqImpl fileTransferOpSet, + IncomingFileTransfer fileTransfer, + Contact sender, + Date date) + { + this.icqProvider = icqProvider; + this.fileTransferOpSet = fileTransferOpSet; + this.incomingFileTransfer = fileTransfer; + this.sender = sender; + this.date = date; + + id = String.valueOf(incomingFileTransfer.getRvSessionInfo() + .getRvSession().getRvSessionId()); + } + + /** + * Uniquie ID that is identifying the request and then the FileTransfer + * if the request has been accepted. + * + * @return the id. + */ + public String getID() + { + return id; + } + + /** + * Returns a String that represents the name of the file that is being + * received. + * If there is no name, returns null. + * @return a String that represents the name of the file + */ + public String getFileName() + { + return incomingFileTransfer.getRequestFileInfo().getFilename(); + } + + /** + * Returns a String that represents the description of the file that is + * being received. + * If there is no description available, returns null. + * + * @return a String that represents the description of the file + */ + public String getFileDescription() + { + return incomingFileTransfer.getInvitationMessage().getMessage(); + } + + /** + * Returns a long that represents the size of the file that is being + * received. + * If there is no file size available, returns null. + * + * @return a long that represents the size of the file + */ + public long getFileSize() + { + return incomingFileTransfer.getRequestFileInfo().getTotalFileSize(); + } + + /** + * Returns a String that represents the name of the sender of the file + * being received. + * If there is no sender name available, returns null. + * + * @return a String that represents the name of the sender + */ + public Contact getSender() + { + return sender; + } + + /** + * Function called to accept and receive the file. + * + * @param file the file to accept + * @return the FileTransfer object managing the transfer + */ + public FileTransfer acceptFile(File file) + { + incomingFileTransfer.setFileMapper(new IcqFileMapper(file)); + + FileTransferImpl inFileTransfer = + new FileTransferImpl( + incomingFileTransfer, + id, sender, file, + FileTransfer.IN); + + FileTransferCreatedEvent event + = new FileTransferCreatedEvent(inFileTransfer, date); + + fileTransferOpSet.fireFileTransferCreated(event); + + incomingFileTransfer.accept(); + + inFileTransfer.fireStatusChangeEvent( + FileTransferStatusChangeEvent.PREPARING); + + return inFileTransfer; + } + + /** + * Function called to refuse the file. + */ + public void rejectFile() + { + try + { + incomingFileTransfer.close(); + + fileTransferOpSet.fireFileTransferRequestRejected( + new FileTransferRequestEvent(fileTransferOpSet, this, date)); + } + catch(IllegalStateException e) + { + logger.debug("Error rejecting file",e); + return; + } + } + + /** + * Class to say where the incoming file should be save + * + * @author Nicolas Riegel + */ + private class IcqFileMapper + implements FileMapper + { + /** + * Destination file + */ + File file = null; + + /** + * Constructor + * + * @param file is the destination file + */ + public IcqFileMapper(File file) + { + this.file = file; + } + + public File getDestinationFile(SegmentedFilename filename) + { + return file; + } + + public File getUnspecifiedFilename() + { + return file; + } + } + +} diff --git a/src/net/java/sip/communicator/impl/protocol/icq/OperationSetFileTransferIcqImpl.java b/src/net/java/sip/communicator/impl/protocol/icq/OperationSetFileTransferIcqImpl.java new file mode 100644 index 000000000..a36f4c1ea --- /dev/null +++ b/src/net/java/sip/communicator/impl/protocol/icq/OperationSetFileTransferIcqImpl.java @@ -0,0 +1,388 @@ +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.impl.protocol.icq; + +import java.io.*; +import java.util.*; + +import net.java.sip.communicator.service.protocol.FileTransfer; +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.service.protocol.event.*; +import net.java.sip.communicator.util.*; + +import net.kano.joscar.rvcmd.*; +import net.kano.joustsim.*; +import net.kano.joustsim.oscar.*; +import net.kano.joustsim.oscar.oscar.service.icbm.ft.*; +import net.kano.joustsim.oscar.oscar.service.icbm.ft.events.*; + +/** + * The ICQ protocol filetransfer OperationSet. + * + * @author Anthony Schmitt + * @author Damian Minkov + */ +public class OperationSetFileTransferIcqImpl + implements OperationSetFileTransfer, + RvConnectionManagerListener +{ + private static final Logger logger = + Logger.getLogger(OperationSetPersistentPresenceIcqImpl.class); + + /** + * A call back to the ICQ provider that created us. + */ + private ProtocolProviderServiceIcqImpl icqProvider = null; + + /** + * A list of listeners registered for file transfer events. + */ + private ArrayList fileTransferListeners + = new ArrayList(); + + /** + * Create a new FileTransfer OperationSet over the specified Icq provider + * @param provider + */ + public OperationSetFileTransferIcqImpl( + ProtocolProviderServiceIcqImpl icqProvider) + { + this.icqProvider = icqProvider; + + icqProvider.addRegistrationStateChangeListener( + new RegistrationStateListener()); + } + + + /** + * Sends a file transfer request to the given toContact by + * specifying the local and remote file path and the fromContact, + * sending the file. + * + * @param toContact the contact that should receive the file + * @param file the file to send + * + * @return the transfer object + * + * @throws IllegalStateException if the protocol provider is not registered + * or connected + * @throws IllegalArgumentException if some of the arguments doesn't fit the + * protocol requirements + */ + public FileTransfer sendFile( Contact toContact, + File file) + throws IllegalStateException, + IllegalArgumentException + { + assertConnected(); + + // Get the aim connection + AimConnection aimConnection = icqProvider.getAimConnection(); + + // Create an outgoing file transfer instance + OutgoingFileTransfer outgoingFileTransfer = + aimConnection.getIcbmService().getRvConnectionManager(). + createOutgoingFileTransfer(new Screenname(toContact.getAddress())); + + String id = String.valueOf(outgoingFileTransfer.getRvSessionInfo() + .getRvSession().getRvSessionId()); + + FileTransferImpl outFileTransfer = new FileTransferImpl( + outgoingFileTransfer, + id, toContact, file, FileTransfer.OUT); + + // Adding the file to the outgoing file transfer + try + { + outgoingFileTransfer.setSingleFile(new File(file.getPath())); + } + catch (IOException e) + { + logger.debug("Error sending file",e); + return null; + } + + // Notify all interested listeners that a file transfer has been + // created. + FileTransferCreatedEvent event + = new FileTransferCreatedEvent(outFileTransfer, new Date()); + + fireFileTransferCreated(event); + + // Sending the file + outgoingFileTransfer.sendRequest( + new InvitationMessage("")); + + outFileTransfer.fireStatusChangeEvent( + FileTransferStatusChangeEvent.PREPARING); + + return outFileTransfer; + } + + /** + * Sends a file transfer request to the given toContact by + * specifying the local and remote file path and the fromContact, + * sending the file. + * + * @param toContact the contact that should receive the file + * @param fromContact the contact sending the file + * @param remotePath the remote file path + * @param localPath the local file path + * + * @return the transfer object + * + * @throws IllegalStateException if the protocol provider is not registered + * or connected + * @throws IllegalArgumentException if some of the arguments doesn't fit the + * protocol requirements + */ + public FileTransfer sendFile( Contact toContact, + Contact fromContact, + String remotePath, + String localPath) + throws IllegalStateException, + IllegalArgumentException + { + return this.sendFile(toContact, new File(localPath)); + } + + /** + * Adds the given FileTransferListener that would listen for + * file transfer requests and created file transfers. + * + * @param listener the FileTransferListener to add + */ + public void addFileTransferListener( + FileTransferListener listener) + { + synchronized(fileTransferListeners) + { + if(!fileTransferListeners.contains(listener)) + { + this.fileTransferListeners.add(listener); + } + } + } + + /** + * Removes the given FileTransferListener that listens for + * file transfer requests and created file transfers. + * + * @param listener the FileTransferListener to remove + */ + public void removeFileTransferListener( + FileTransferListener listener) + { + synchronized(fileTransferListeners) + { + this.fileTransferListeners.remove(listener); + } + } + + /** + * Utility method throwing an exception if the stack is not properly + * initialized. + * @throws java.lang.IllegalStateException if the underlying stack is + * not registered and initialized. + */ + private void assertConnected() + throws IllegalStateException + { + if (icqProvider == null) + throw new IllegalStateException( + "The provider must be non-null and signed on the " + +"service before being able to send a file."); + else if (!icqProvider.isRegistered()) + throw new IllegalStateException( + "The provider must be signed on the service before " + +"being able to send a file."); + } + + /** + * Function called when a icq file transfer request arrive + * @param manager the joustsim manager + * @param transfer the incoming transfer + */ + public void handleNewIncomingConnection( + RvConnectionManager manager, IncomingRvConnection transfer) + { + if (transfer instanceof IncomingFileTransfer) + { + logger.trace("Incoming Icq file transfer request " + transfer.getClass()); + + if(!(transfer instanceof IncomingFileTransfer)) + { + logger.warn("Wrong file transfer."); + return; + } + + OperationSetPersistentPresenceIcqImpl opSetPersPresence + = (OperationSetPersistentPresenceIcqImpl) + icqProvider.getOperationSet( + OperationSetPersistentPresence.class); + + Contact sender = + opSetPersPresence.findContactByID( + transfer.getBuddyScreenname().getFormatted()); + + IncomingFileTransfer incomingFileTransfer = + (IncomingFileTransfer)transfer; + + final Date newDate = new Date(); + final IncomingFileTransferRequest req = + new IncomingFileTransferRequestIcqImpl( + icqProvider, + this, + incomingFileTransfer, sender, newDate); + + // this handels when we receive request and before accept or decline + // it we receive cancel + transfer.addEventListener(new RvConnectionEventListener() { + public void handleEventWithStateChange( + RvConnection transfer, + RvConnectionState state, + RvConnectionEvent event) + { + if (state==FileTransferState.FAILED + && event instanceof BuddyCancelledEvent) + { + fireFileTransferRequestCanceled( + new FileTransferRequestEvent( + OperationSetFileTransferIcqImpl.this, + req, + newDate)); + } + } + + public void handleEvent(RvConnection arg0, RvConnectionEvent arg1) + {} + }); + + fireFileTransferRequest( + new FileTransferRequestEvent(this, req, newDate)); + } + } + + /** + * Delivers the specified event to all registered file transfer listeners. + * + * @param event the EventObject that we'd like delivered to all + * registered file transfer listeners. + */ + private void fireFileTransferRequest(FileTransferRequestEvent event) + { + Iterator listeners = null; + synchronized (fileTransferListeners) + { + listeners = new ArrayList + (fileTransferListeners).iterator(); + } + + while (listeners.hasNext()) + { + FileTransferListener listener = listeners.next(); + + listener.fileTransferRequestReceived(event); + } + } + + /** + * Delivers the specified event to all registered file transfer listeners. + * + * @param event the EventObject that we'd like delivered to all + * registered file transfer listeners. + */ + void fireFileTransferRequestRejected(FileTransferRequestEvent event) + { + Iterator listeners = null; + synchronized (fileTransferListeners) + { + listeners = new ArrayList + (fileTransferListeners).iterator(); + } + + while (listeners.hasNext()) + { + FileTransferListener listener = listeners.next(); + + listener.fileTransferRequestRejected(event); + } + } + + /** + * Delivers the specified event to all registered file transfer listeners. + * + * @param event the EventObject that we'd like delivered to all + * registered file transfer listeners. + */ + void fireFileTransferRequestCanceled(FileTransferRequestEvent event) + { + Iterator listeners = null; + synchronized (fileTransferListeners) + { + listeners = new ArrayList + (fileTransferListeners).iterator(); + } + + while (listeners.hasNext()) + { + FileTransferListener listener = listeners.next(); + + listener.fileTransferRequestCanceled(event); + } + } + + /** + * Delivers the file transfer to all registered listeners. + * + * @param fileTransfer the FileTransfer that we'd like delivered to + * all registered file transfer listeners. + */ + void fireFileTransferCreated(FileTransferCreatedEvent event) + { + Iterator listeners = null; + synchronized (fileTransferListeners) + { + listeners = new ArrayList + (fileTransferListeners).iterator(); + } + + while (listeners.hasNext()) + { + FileTransferListener listener = listeners.next(); + listener.fileTransferCreated(event); + } + } + + /** + * Our listener that will tell us when we're registered to + */ + private class RegistrationStateListener + implements RegistrationStateChangeListener + { + /** + * The method is called by a ProtocolProvider implementation whenever + * a change in the registration state of the corresponding provider had + * occurred. + * @param evt ProviderStatusChangeEvent the event describing the status + * change. + */ + public void registrationStateChanged(RegistrationStateChangeEvent evt) + { + logger.debug("The provider changed state from: " + + evt.getOldState() + + " to: " + evt.getNewState()); + + if (evt.getNewState() == RegistrationState.REGISTERED) + { + AimConnection aimConnection = icqProvider.getAimConnection(); + aimConnection.getIcbmService().getRvConnectionManager(). + addConnectionManagerListener(OperationSetFileTransferIcqImpl.this); + } + } + } +} diff --git a/src/net/java/sip/communicator/impl/protocol/icq/ProtocolProviderServiceIcqImpl.java b/src/net/java/sip/communicator/impl/protocol/icq/ProtocolProviderServiceIcqImpl.java index 8af1dd436..0a35392a0 100644 --- a/src/net/java/sip/communicator/impl/protocol/icq/ProtocolProviderServiceIcqImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/icq/ProtocolProviderServiceIcqImpl.java @@ -528,6 +528,12 @@ protected void initialize(String screenname, supportedOperationSets.put( OperationSetExtendedAuthorizations.class.getName(), extendedAuth); + + OperationSetFileTransferIcqImpl fileTransferOpSet = + new OperationSetFileTransferIcqImpl(this); + supportedOperationSets.put( + OperationSetFileTransfer.class.getName(), + fileTransferOpSet); } isInitialized = true; diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetFileTransferYahooImpl.java b/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetFileTransferYahooImpl.java index 92ff7e20c..4ee1603ef 100644 --- a/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetFileTransferYahooImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetFileTransferYahooImpl.java @@ -262,6 +262,29 @@ private void fireFileTransferRequest(FileTransferRequestEvent event) } } + /** + * Delivers the specified event to all registered file transfer listeners. + * + * @param event the EventObject that we'd like delivered to all + * registered file transfer listeners. + */ + void fireFileTransferRequestCanceled(FileTransferRequestEvent event) + { + Iterator listeners = null; + synchronized (fileTransferListeners) + { + listeners = new ArrayList + (fileTransferListeners).iterator(); + } + + while (listeners.hasNext()) + { + FileTransferListener listener = listeners.next(); + + listener.fileTransferRequestCanceled(event); + } + } + private int getStateMapping(int s) { switch(s) @@ -336,13 +359,23 @@ public void statusChanged(SessionFileTransferEvent ev) int newState = ev.getState(); + if(newState == SessionFileTransferEvent.CANCEL + || newState == SessionFileTransferEvent.FAILED + || newState == SessionFileTransferEvent.RECEIVED + || newState == SessionFileTransferEvent.REFUSED + || newState == SessionFileTransferEvent.SENT) + { + // this is an final state so remove it from active filetransfers + activeFileTransfers.remove(ev.getId()); + } + if(ftObj instanceof IncomingFileTransferRequest) { if(newState == SessionFileTransferEvent.REFUSED) { IncomingFileTransferRequestYahooImpl req = (IncomingFileTransferRequestYahooImpl)ftObj; - fireFileTransferRequestRejected( + fireFileTransferRequestCanceled( new FileTransferRequestEvent(this, req, req.getDate())); return; } diff --git a/test/net/java/sip/communicator/slick/protocol/generic/TestOperationSetFileTransfer.java b/test/net/java/sip/communicator/slick/protocol/generic/TestOperationSetFileTransfer.java index 873151b98..2fe06fe78 100644 --- a/test/net/java/sip/communicator/slick/protocol/generic/TestOperationSetFileTransfer.java +++ b/test/net/java/sip/communicator/slick/protocol/generic/TestOperationSetFileTransfer.java @@ -302,8 +302,8 @@ public void testSenderCancelBeforeAccepted() fileTransferRequestEvent = (FileTransferRequestEvent)receiverFTListerner.collectedEvents.get(0); - assertTrue("FileTransfer must be rejected" - ,receiverFTListerner.isRejected()); + assertTrue("FileTransfer must be canceled" + ,receiverFTListerner.isCanceled()); } finally { @@ -730,6 +730,7 @@ public class FileTransferEventCollector { public ArrayList collectedEvents = new ArrayList(); private boolean rejected = false; + private boolean canceled = false; private FileTransferStatusEventCollector statusCollector = null; private String name = null; @@ -844,6 +845,15 @@ public void fileTransferRequestRejected(FileTransferRequestEvent event) public void fileTransferRequestCanceled(FileTransferRequestEvent event) { + synchronized(this) + { + logger.debug( + name + " Collected evt("+collectedEvents.size()+")= "+event); + + canceled = true; + this.collectedEvents.add(event); + notifyAll(); + } } public void clear() @@ -859,6 +869,14 @@ public boolean isRejected() { return rejected; } + + /** + * @return the rejected + */ + public boolean isCanceled() + { + return canceled; + } } /**