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;
+ }
}
/**